Talk:First class environments

From Rosetta Code


So it's what, the thing we normally call "closure"? --Ledrug 09:14, 30 June 2011 (UTC)

No, because a closure cannot be handled independently from the code, e.g. stored in a variable and activated at some other time with a piece of code.--Abu 09:19, 30 June 2011 (UTC)
This looks like what most people would call an "object". Since we already have examples of objects, I am not sure how this task is interesting. --Rdm 20:56, 30 June 2011 (UTC)
I guess it's more about directly rebinding variable names than accessing objects; in the PicoLisp example the job funtions accessed N as if it were the only instance out there. The C cheat code is more of an object, though. --Ledrug 21:22, 30 June 2011 (UTC)
If that's the case -- if this is a dictionary or whatever -- perhaps the task ought to have something about dynamically generated names? --Rdm 21:28, 30 June 2011 (UTC)
A dictionary encapsulates keys and values (must be explicitly accessed/fetched), but not variables and their values (transparently changing the behavior of the code).--Abu 06:00, 1 July 2011 (UTC)
No, nothing to do with objects. Objects encapsulate code and data. Environments encapsulate variables and their values (closures minus code).--Abu 06:00, 1 July 2011 (UTC)
Ok, I give up. I have implemented the task (J implementation). The natural way of implementing it used objects. If I have failed to satisfy any of the task requirements, please let me know which requirements I have failed to satisfy. --Rdm 13:07, 2 July 2011 (UTC)
What are variables other than references to data and/or code? And, if it's that variables have mutable names (which would not actually be the case in many compiled languages), how is a variable name any different from a dictionary key? Using different words does not make the concept different -- you have to spell out the differences or illustrate them with examples. --Rdm 10:54, 1 July 2011 (UTC)
A variable is a direct reference to data (the name of a memory location), while a dictionary is a data structure, which in turn has named elements. These are different concepts. A variable "phone" might point to a dictionary, and a key "alice" might be used to specify a location in the dictionary's memory area, but that's rather a "sub-variable". An expression "phone['alice']" is still an access to the original variable "phone", just with an offset or some lookup mechanism. "phone" is known by the program code directly, because it is in the program's environment. If that environment is implemented in the language as a kind of implicit dictionary, it is OK, just that for this task the environment (the association between "phone" and the contents of the corresponding memory location) must be manipulated as a first class datatype.--Abu 13:15, 1 July 2011 (UTC)
Ok, certainly: a dictionary is a collection of named references, and is not a single reference. Also: an entry in the dictionary was what I would think of as filling the same role as a variable -- I was not trying to suggest that the dictionary as a whole would fill the role of a single variable. So... this would make the dictionary key equivalent to a variable name for this task and a dictionary value equivalent to a variable value for this task? But I'm still not clear what this task adds to existing tasks (for example, considering the "Collections" task). --Rdm 19:35, 1 July 2011 (UTC)
It is not about data structures like dictionaries or collections in general, but about how to use such structures to change the program's variable bindings. --Abu 12:51, 2 July 2011 (UTC)
Perhaps the concept of first class environments is foreign to many people because most programming languages don't support them natively. I'm not sure, but one reason may be that they don't fit well into statically compiled languages. For Python, they should be trivial to implement with dictionaries.
If first class environments are a true language feature, they give additional control to the programmer, over closures, continuations and other constructs. Not a big thing, but useful. For example, the PicoLisp GUI uses them to pass state between HTML pages and forms/dialogs across HTTP transfers. --Abu 09:32, 2 July 2011 (UTC)
This is interesting. In some languages variable names are really just dictionaries, such as Perl package variables or "named variables" in PostScript. This fact may be used both for and against having this task, but personally I think the task is worthwhile, even if only to show how each language handles name lookups. --Ledrug 22:34, 1 July 2011 (UTC)
Perhaps this article helps to explain the issue?!wiki?firstClassEnvironments --Abu 07:22, 9 June 2012 (UTC)
Unless we are saying that we want to implement picolisp for this task, basically that page just seems to be saying that we want distinct sets of symbols, where the same names can resolve to different values depending on which set we are using. That's a "first class environment" in the context of the page you refer to, but a dictionary accomplishes the same thing, as does an object (though, depending on the language, a dictionary or an object might use different syntax). There can be *subtle* syntactic issues between otherwise similar constructs. But those are not relevant here, because subtle syntactic issues are language specific. --Rdm 13:17, 9 June 2012 (UTC)
I don't think a dictionary does the same. It doesn't bind variables. A proper implementation e.g. in C would be to have the code use global variables, and the environment sets those variables dynamically before executing the code. A dictionary or object is not concerned about binding variables, instead they allow a dynamic lookup of values, which is something completely different. I was in the hope that the above article makes this clear, but obviously it doesn't. --Abu 16:11, 9 June 2012 (UTC)
Is the following more clear? While you can simply execute 'print(x,y)' after setting an environment, you have to call (in pseudo-code) 'print(get(dict,x), get(dict,y))' for a dictionary, and 'print(object->x, object->y)' for an object. In both cases, you still carry an explicit binding around with you, either the dictionary 'dict' or the object. --Abu 16:18, 9 June 2012 (UTC)
Except "binding a variable" may be exactly what a dictionary does *depending on the language you are working in*. The distinction between "binding a variable" and "associating a name with a value" is not one that is meaningful across languages. It's only a distinction when you have specific implementations of "binding" and "associating" which you are trying to distinguish between. For that matter, the distinction between a "variable" and a "name" is also a language-specific issue (and sometimes a context-dependent issue within a language). For that matter, x is not a valid variable name in some languages (perl is a good example for that). Also, even in picolisp you can take an expression and modify it so that what originally looked like a variable reference is turned into an appropriate dictionary reference. Also, the distinction between "first class" and "not first class" is itself language specific and context specific -- "first class" is typically shorthand for "simple to use" but that's a subjective and comparative and context dependent issue. It can be quite meaningful in a narrow context but it loses a lot when you try to treat it like it's something generic. --Rdm 16:52, 9 June 2012 (UTC)
That said, if you will allow that in some languages "dictionary" and "first class environment" are identical things, it is true that there's a meaningful distinction between them in some other languages. --Rdm 16:55, 9 June 2012 (UTC)

Concerning the question whether the C solution "fits the spirit": I would say yes, though instead of switching the pointers to 'sec' and 'cnt' I would save and restore the actual values. This would better simulate the "binding" of the "environments".--Abu 15:17, 30 June 2011 (UTC)

Well, that's quite a bit more work. Right now I can just swap the links (addresses) and forget about it (which is in a sense more "real"), if I copy values, I'd have to copy them back after each job switch, can't exit job control loop whenever I want, etc. The way I look at it, just pretend the "*" is a special marker for environment variables. In the worst case, the job function itself can copy and restore them to stack if really needed. --Ledrug 16:40, 30 June 2011 (UTC)


What is the exact relationship between this and the flyweight pattern? --Michael Mol 16:44, 30 June 2011 (UTC)

Is there any at all? --Ledrug 16:47, 30 June 2011 (UTC)
I can't detect any. Flyweight patterns seem to be mainly concerned about sharing data structures, not about runtime variable bindings.--Abu 16:58, 30 June 2011 (UTC)
Ledrug's initial question was quite close. A "closure" is a combination of environment and code. AFAIK, in most languages the environment cannot be separated from a closure, and stored, retrieved and manipulated explictly. In PicoLisp it is the other way round: Environments can be constructed from normal Lisp data, and then perhaps be used to build a closure, but also for other purposes.--Abu 17:17, 30 June 2011 (UTC)


The concept seems close to Runtime_evaluation/In_an_environment. The initial implementation there was Common Lisp, by the way. —Sonia 18:36, 30 June 2011 (UTC)

Yes. However, Runtime_evaluation/In_an_environment requires the manipulation of environment contents (setting a free variable), while this task is about handling environments as first class objects (maintaining a set of environments).--Abu 05:50, 1 July 2011 (UTC)