Request: Function to give context given symbol

Q&A's, tips, howto's
itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Request: Function to give context given symbol

Post by itistoday »

This would be a lifesaver, I've found myself needing this so many times: a function to give me the context of a symbol.

I.e. check out this awesome function:

Code: Select all

(define-smacro (for-query-with-db db query ctx)
	(letn (db (eval db) sql (db:prepare-sql query) keys '())
		(dotimes (i (sql:col-count))
			(push (sym (upper-case (sql:col-name i)) ctx) keys -1)
		)
		(push-autorelease-pool) ; in case we have blobs
		(while (list? (setf values (sql:next-row)))
			(eval (expand (cons 'begin $args) (unify keys values)))
		)
		(pop-autorelease-pool)
		(deallocate sql)
	)
)
It can't live because the body ($args) uses symbols in a different context. I have to manually *tell* 'sym' what context the symbols in the body are coming from.

This function is going to be in Dragonfly 0.61, it will let you do stuff like this:

Code: Select all

<table>
	<tr><td>ID</td><td>Name</td><td>Age</td></tr>
	<% (for-query-with-db db "SELECT rowid,name,age FROM people" %>
		<tr><td><%=ROWID%></td><td><%=NAME%></td><td><%=AGE%></td></tr>
	<% ) %>
</table>
That's pretty great, but currently this will just show a bunch of nil's. To get it to show the right values I have to hack it up and make it ugly:

Code: Select all

<table>
	<tr><td>ID</td><td>Name</td><td>Age</td></tr>
	<% (for-query-with-db db "SELECT rowid,name,age FROM people" DF %>
		<tr><td><%=ROWID%></td><td><%=NAME%></td><td><%=AGE%></td></tr>
	<% ) %>
</table>
I could get rid of that 'DF' on the end if there was a (sym->ctx) function available. There are so many other cool things you could do if such a function existed. Can such a function be brought into newLISP?

Edit: updated function definition to use 'expand' and 'unify'
Last edited by itistoday on Tue Feb 16, 2010 3:00 am, edited 1 time in total.
Get your Objective newLISP groove on.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

There is one in the next version:

Code: Select all

newLISP v.10.1.11 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (setf s 'Foo:bar)
Foo:bar
> (path s)
Foo
> (context? (path s))
true
> (context (path s))
Foo
Foo> 

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

Awesome! Thanks Lutz! :-D

(I would only advise against using 'path' for the name, as that is probably used in a lot of existing newlisp code, and making it a primitive would break all of that code).
Get your Objective newLISP groove on.

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

Also, will it work with non-symbols? i.e:

Code: Select all

(define-macro (blah x) (path x))
(blah "asdf") => MAIN
Get your Objective newLISP groove on.

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Re: Request: Function to give context given symbol

Post by TedWalther »

Perhaps "path" would be too easily confused with basename/filename type of operations? Perhaps "context-of" would be a better name?

Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Re: Request: Function to give context given symbol

Post by Kazimir Majorinc »

I like "context-of". Use of "of", "is", "from", "to" etc. is, I believe, good naming practice.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

Symbol names as strings:

It cannot work on strings because the context of a symbol is encoded with the symbol. The symbol with the name "blah" could be in several contexts. One could check if "blah" is present in a specific context:

Code: Select all

(sym "blah" (context) nil) => nil
(sym "blah" MAIN nil) => nil
(sym "blah" Foo nil) => Foo:blah
This tells us that "blah" is not present in the current context and not in MAIN, but is defined in Foo. The 'nil' parameter tells 'sym' not to create the symbol, if not present.

Naming of the new function:

Name clashes with new function names are always a possibility, and we always have had these in the past. I remember introducing 'name', which caused a lot of clashes being used in many web forms. I don't think it is a good practice to make the name more complicated for the sake of avoiding name clashes. Perhaps it should be practice to making variable names in programs more descriptive.

Conceptually 'name' and 'path' belong together:

Code: Select all

(set 's 'Foo:bar)
(= s (sym (name s) (path s))) => true
In other areas in computing, i.e. file systems, the same labels are used to describe tree structures. See: path-name or pathname, path in a symbol tree.

Fortunately built-in symbols are protected. So a name clash is pretty obvious accompanied by an error message.

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Re: Request: Function to give context given symbol

Post by TedWalther »

Thanks for the reminder about the (name) function. I see your point, and agree; name and path are a good pairing.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

Lutz wrote:Symbol names as strings:

It cannot work on strings because the context of a symbol is encoded with the symbol. The symbol with the name "blah" could be in several contexts. One could check if "blah" is present in a specific context:
I think you misunderstood me, and I think it's my fault. I think what I'm asking for is may not be addressed by this path function. In the original function that I gave, what I want to be able to do is to find out the context an fexpr is called in. Here's an updated version of it using path:

Code: Select all

(define-smacro (for-query-with-db db query)
	(letn (db (eval db) sql (db:prepare-sql (eval query)) keys '())
		(dotimes (i (sql:col-count))
			(push (sym (upper-case (sql:col-name i)) (path query)) keys -1)
		)
		(push-autorelease-pool) ; in case we have blobs
		(while (list? (setf values (sql:next-row)))
			(eval (expand (cons 'begin $args) (unify keys values)))
		)
		(pop-autorelease-pool)
	)
)
See the (path query)? I want that to return the context that the fexpr was called in, because otherwise I can't use 'for-query-with-db' in any context other than its own (without manually specifying it when calling it).
Get your Objective newLISP groove on.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

You mean the callee knowing about the caller?

Code: Select all

(define (Bar:func) (caller)) ; or (path (caller))
(define (Foo:func) (Bar:func))

(Foo:func) => Foo:func  ; or Foo

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

Lutz wrote:You mean the callee knowing about the caller?

Code: Select all

(define (Bar:func) (caller)) ; or (path (caller))
(define (Foo:func) (Bar:func))

(Foo:func) => Foo:func  ; or Foo
Yes! (path (caller)) looks like it should work, especially if it works with macros as well. I can only imagine the kinds of things you could do with this. Many thanks!
Get your Objective newLISP groove on.

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: Request: Function to give context given symbol

Post by xytroxon »

I always think of the file system when I see path...

And why wouldn't it be called root? As in finding the symbol's root context... Calling it path also seems to imply the path of a nested context...

And Dragonfly uses "path" in it's framework libraries, breaking a site's installation on a minor newLISP release...

If I remember right, Clojure uses find-ns ie find name space...

From the newlisp manual: context
-----------------------------------------------
In the second syntax, context can be used create symbols in a namespace.
-----------------------------------------------
(Also found a manual error: can be used to create symbols ;)

Code: Select all

newLISP v.10.1.11 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (setf s 'Foo:bar)
Foo:bar
> (namespace s)
Foo
> (context? (namespace s))
true
> (context (namespace s))
Foo
Foo> 
-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

I second (third?) xytroxon's comments, and I think he picked a good names for it; 'namespace' is good, 'root' is slightly less descriptive and more likely to break existing code, but it's still better than 'path'. I think breaking existing code frequently by using commonly used names like 'name' and 'path' is a bad thing, and could scare people away from newlisp. Further, 'path' is a legitimate name to use for many other things, it would be a great loss to not be able to use it.
Get your Objective newLISP groove on.

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

Re: Request: Function to give context given symbol

Post by m i c h a e l »

Since contexts are namespaces in newLISP, wouldn't namespace and context be in conflict?

m i c h a e l

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

m i c h a e l wrote:Since contexts are namespaces in newLISP, wouldn't namespace and context be in conflict?
That's a good point, in light of that I vote for Kazimir's context-of.
Get your Objective newLISP groove on.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

I still like 'path' best, but how about 'space' ? What does Cormullion think about all this? I want something short!

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Re: Request: Function to give context given symbol

Post by TedWalther »

Holy smokes, this thread has gone on long. Now that Lutz explained it, I like his original two choices of name and path.

But if we are voting on alternatives, then I would vote to rename the functions symname and symcontext And for teh win in shortness, how about symnm and symct? nm being an abbreviation for "name" and ct being an abbreviation for "context". symnm is only 1 character longer than name, and symct is only 1 character longer than path. And I think they signal pretty well what they do, ie, operating on symbols.

Code: Select all

(setq a 'Foo:b)

(symname a) => b
(symname 'Foo:b) => b

(symcontext a) => Foo
(symcontext 'Foo:b) => Foo
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

Lutz wrote:I still like 'path' best, but how about 'space' ? What does Cormullion think about all this? I want something short!
What's wrong with context-of? It's not going to be a very often used function, and there are plenty of newLISP functions that are longer (write-buffer, bayes-query, remove-file, etc.). context-of isn't long, and it's very clear what its purpose is.

Neither 'path' nor 'space' tell me that the function gives the context of a given symbol.

I also like TedWalther's alternate suggestions as that would give us back 'name', but I would suggest they be hyphenated to fit with the rest of newLISP's functions: sym-name, sym-context.
Get your Objective newLISP groove on.

itistoday
Posts: 429
Joined: Sun Dec 02, 2007 5:10 pm
Contact:

Re: Request: Function to give context given symbol

Post by itistoday »

There are several neat aspects to sym-context and sym-name:
  1. They tell you almost exactly what the function takes and what it returns
  2. They avoid conflicts in code with commonly used symbol names
  3. They "complete the picture" with sym, creating the "sym family of functions"
Get your Objective newLISP groove on.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

How about 'prefix' ?

Code: Select all

(setq s 'Foo:bar)

(prefix s) => Foo
A more generic term, not as specific as the other suggestions, but short, immediately understood, and name clashes not very likely.

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

Re: Request: Function to give context given symbol

Post by m i c h a e l »

Yes, I like prefix, but does that mean we can change name to suffix, too? Like many others, I'm constantly bumping into name because it's such a natural name for a name ;-)

m i c h a e l

kks
Posts: 13
Joined: Sat Dec 26, 2009 12:05 am

Re: Request: Function to give context given symbol

Post by kks »

I like itistoday's `sym-context`.

What if "warning" is used instead of "error" when name clashes (redefining protected names)? Old code can be run without changes, because it didn't mean to use the "new" definition of the names.

By the way, I use a naming convention that starts "variables" with an uppercase letter (got the idea from PicoLisp), to prevent name clashes with "functions". (But then they may clash with "classes"!)

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

Thanks for all the suggestions!

It will be 'prefix' then. It is a term often used in science with Latin roots and probably recognizable by many non-English speakers too.

sym-name and sym-context where good suggestions too, but I am trying to slowly move to shorter (but still recognizable) function names. E.g. many versions back sym was symbol and int was integer (integer is still recognized but not documented anymore).

In version 10.2.0 'read' and 'write' will be allowed as shorter writing of the elementary I/O operations 'read-buffer' and 'write-buffer' which will still be valid for a long time.

I share Michaels feeling about clashing with 'name', which also still happens to me, on the other side I cannot think of a better word for it. I decided for 'prefix' because I started to agree that there are to much clashes with 'path', e.g. there is already 'real-path' in newLISP referring to files/directories.

I am also not sure if 'suffix' would be technically correct. As I see the meaning of the words prefix and suffix, it is: prefix-TheName-suffix, so in newLISP Foo:bar Foo is the prefix and bar is TheName. As Michael suggests it would be: Foo is the prefix and bar is the suffix (something missing in the middle ?!). What I mean is, that prefix/suffix implies that something is in the middle surrounded by prefix and suffix, but I may be wrong on this. I consulted http://www.dict.org

xytroxon suggested root for the prefix, then name could be perhaps 'leaf' as in <prefix>:<leaf>, … sigh … still don't like it.

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

Re: Request: Function to give context given symbol

Post by m i c h a e l »

You're right about suffix, Lutz. I was half-joking about the suggestion, but I'm serious about the problems encountered with name (as you acknowledge here). When I asked Melissa—the source of all things grammatical—what comes between prefix and suffix, she said term. Would this work?

m i c h a e l

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Request: Function to give context given symbol

Post by Lutz »

Yes, 'term' absolutely works and it is short too and a beautiful word! 'term' will be introduced in the coming release version 10.2.0 (or any development version before it).

I knew, we needed and English professor to solve this ;-), many thanks to Melissa!

Code: Select all

(setq s 'Foo:bar)

(= s (sym (term s) (prefix s))) => true
Ps: a quick check in the standard modules shows, that gmp.lsp, mysql.lsp, odbc.lsp, postgres.lsp sqlite.lsp and stat.lsp are affected. So perhaps we keep both for some time and let 'name' die slowly through deprecation; having the reference entry for 'name' saying: "please use 'term' instead", but keep it working for some time.

Locked