Thread View: comp.lang.functional
15 messages
15 total messages
Started by Surendar Chandra
Fri, 26 Apr 1991 20:16
Help needed with behaviour of SML
Author: Surendar Chandra
Date: Fri, 26 Apr 1991 20:16
Date: Fri, 26 Apr 1991 20:16
27 lines
1474 bytes
1474 bytes
Hi, This is my first posting on this group. I do not even know if this question is appropriate in this group. Anyway, I am currently implementing a subset of the STandard ML as part of my course project and find the behavior of SML quite confusing in the following case. > val a = 1; > a ; | 1 : int ; > fun b c = c * a ; > b 2 ; | 2 : int ; > val a = 3; > b 2 ; | 2 : int ; ^^^^^^^^^^ Why does it do it like this.. Why doesn't it look up at the current value of the variable 'a'. Why does it store the current value of 'a' in the function during compilation itself? WHat is the logic behind this? I could not lay my hands on a good reference for SML and most of the books don't seem to talk about this at all. Thanks in advance for any help, surendar ============================================================================ Surendar Chandra 602-894-2614 surendar@enuxva.eas.asu.edu
Re: Help needed with behaviour of SML
Author: Thomas M. Breuel
Date: Sat, 27 Apr 1991 02:27
Date: Sat, 27 Apr 1991 02:27
47 lines
2180 bytes
2180 bytes
In article <9104262016.AA28063@enuxha.eas.asu.edu> surendar@ENUXHA.EAS.ASU.EDU (Surendar Chandra) writes: This is my first posting on this group. I do not even know if this question is appropriate in this group. Anyway, I am currently implementing a subset of the STandard ML as part of my course project and find the behavior of SML quite confusing in the following case. > val a = 1; > a ; | 1 : int ; > fun b c = c * a ; > b 2 ; | 2 : int ; > val a = 3; > b 2 ; | 2 : int ; ^^^^^^^^^^ Why does it do it like this.. Why doesn't it look up at the current value of the variable 'a'. Why does it store the current value of 'a' in the function during compilation itself? WHat is the logic behind this? I could not lay my hands on a good reference for SML and most of the books don't seem to talk about this at all. There are several reasons. Here are some simple ones: One is that otherwise it would be difficult to preserve type correctness: > val a = 1; > fun f x = x * a; > val a = "abc"; (* ??? *) Not allowing you to define the variable a to be of a different type would make program development a hassle (you couldn't ever change your mind about the type that you gave some global variable). But if you do allow the user to change the type "destructively", none of the original type checking is still valid. Another reason is that allowing bindings to change would inhibit lots of compiler optimizations. If you want a variable that can be modified, use ref: > val a = ref 1; > fun f x = x * !a; > a := 3; Thomas.
Re: Help needed with behaviour of SML
Author: Bennet Vance
Date: Sat, 27 Apr 1991 04:28
Date: Sat, 27 Apr 1991 04:28
34 lines
1752 bytes
1752 bytes
In article <TMB.91Apr26222738@volterra.ai.mit.edu> tmb@ai.mit.edu (Thomas M. Breuel) writes: >In article <9104262016.AA28063@enuxha.eas.asu.edu> surendar@ENUXHA.EAS.ASU.EDU (Surendar Chandra) writes: > ...[I] find the behavior of SML quite confusing in the following case. > > > val a = 1; > > a ; > | 1 : int ; > > fun b c = c * a ; > > b 2 ; > | 2 : int ; > > val a = 3; > > b 2 ; > | 2 : int ; > ^^^^^^^^^^ Why does it do it like this.. Why doesn't it look up at the current > value of the variable 'a'...? > >There are several reasons. Here are some simple ones... Here is another one, or another way to think about it: At "val a = 3", you are not changing the binding of "a" from 1 to 3. Rather, you are introducing a new variable "a" that happens to have the same name as a previously defined variable. Just as when you introduce in an inner scope a variable that hides a variable in an outer scope, here also you do not make the previous variable binding go away, but you do make it invisible. The only difference is that in an interactive SML session, you will never come out of the new scope, and the old "a" will never be seen again--except when you invoke functions like "b" that refer to it. Bennet
Re: Help needed with behaviour of SML
Author: Markus Freericks
Date: Sat, 27 Apr 1991 11:00
Date: Sat, 27 Apr 1991 11:00
35 lines
1872 bytes
1872 bytes
In article <9104262016.AA28063@enuxha.eas.asu.edu> surendar@ENUXHA.EAS.ASU.EDU (Surendar Chandra) writes: > > val a = 1; > > a ; > | 1 : int ; > > fun b c = c * a ; > > b 2 ; > | 2 : int ; > > val a = 3; > > b 2 ; > | 2 : int ; > ^^^^^^^^ Why does it do it like this.. Why doesn't it look up at the current > value of the variable 'a'. Why does it store the current value of 'a' in the > function during compilation itself? WHat is the logic behind this? I could > not lay my hands on a good reference for SML and most of the books don't seem > to talk about this at all. ML is a 'real', i.e. 'single-assignment' language. Once a variable is defined, it cannot change its value. So, when you define a=1, then a=3, the second time you create a new variable hiding the old one. So, ML not being dynamically scoped, the function b has as its closure the environment at the time of its creation, i.e. seeing only the 'old' a. You need not think that that value of a is compiled into the function b (although this could be done); its simply a consequence of not being able to alter something once its created. Hope that helps, Markus -- Markus Freericks phone: +49-30-4034110 Oranienburger Str. 142 email: mfx@opal.cs.tu-berlin.de 1000 Berlin 26 FRG or mfx%tubopal@DB0TUI11.BITNET
Re: Help needed with behaviour of SML
Author: Steve Knight
Date: Tue, 30 Apr 1991 11:02
Date: Tue, 30 Apr 1991 11:02
14 lines
1098 bytes
1098 bytes
surendar asks about the top-level environment in SML: > Why doesn't it look up at the current > value of the variable 'a'. Why does it store the current value of 'a' in the > function during compilation itself? WHat is the logic behind this? Folks coming from other interactive environments are usually surprised by this unfortunate behaviour. Roughly speaking, being able to redefine existing top-level identifiers allows the possibility of introducing type-errors in previously type-checked functions. There are other arguments which are based on the uniformity of top-level and all other levels. I regard these as spurious. Steve
Re: Help needed with behaviour of SML
Author: Chris Dollin
Date: Thu, 02 May 1991 07:48
Date: Thu, 02 May 1991 07:48
37 lines
1910 bytes
1910 bytes
Someone writes: > ...[I] find the behavior of SML quite confusing in the following case. > > > val a = 1; > > a ; > | 1 : int ; > > fun b c = c * a ; > > b 2 ; > | 2 : int ; > > val a = 3; > > b 2 ; > | 2 : int ; > ^^^^^^^^^^ Why does it do it like this.. Why doesn't it look up at the current > value of the variable 'a'...? > Here's another one. SML is an interactive incremental development language. This means that when you find an error in a function definition, all you need to do is to redefine the function and .... Funny, this useful feature of interactive langauges seems to have gone wrong. I'll just have to load all the code I've compiled since then. I wonder what modules that covers? The ML definition is fine for batch use, but for incremental development it's a pigs trotter. [*Why* is ML like this? Because it's a functional language, ie, it has no assignment, so values don't change. Apart, of course, from arrays, and references. Pah.] -- Regards, Kers. | "You're better off not dreaming of the things to come; Caravan: | Dreams are always ending far too soon."
ML's wierdness in interactive script. (sorry if you see this twice)
Author: Shail Aditya Gupta
Date: Sat, 04 May 1991 07:05
Date: Sat, 04 May 1991 07:05
59 lines
3327 bytes
3327 bytes
Okay, here is my $0.02 worth. The program in question is: > val a = 1; > a ; | 1 : int ; > fun b c = c * a ; > b 2 ; | 2 : int ; > val a = 3; > b 2 ; | 2 : int ; ^^^^^^^^^^ Why does it do it like this.. ML's interactive script can be viewed like a giant, never ending ML program, with each statement being defined in the lexical scope of all the previous ones. If you view it this way, as it was pointed out by others, it is logical and reasonable that the second definition of "a" shadows the first, but the first had been "closed over" in the lexical closure environment of the function "b", which can never be destroyed, only further shadowed, (unless "a" happened to be a "ref" variable and you side-effected it). In this sense, I view ML's interactive script as non-incremental, by which I mean no forward references are allowed, explicit grouping of mutually recursive definitions is required via "let rec" declarations (as against simple "let" bound polymorphic definitions), and it is not possible to edit existing definitions (only shadow them with new ones). One way to look at this is that ML does not support "dynamic linking" at the toplevel script. Note this is not the same as "dynamic scoping" which can also do this job but does more. There are other languages in the same class as ML, notably Miranda and Id, that do support forward references in their scripts etc. Still, Miranda does not measure up to my concept of incremental program development, since it supports only environmentally "closed" files to be compiled as a unit (correct me if I am wrong). Id, on the other hand, is no less flexible and incremental than Lisp or Scheme even though it does fully static ML-style, and SOUND type inferencing. (I should know, this was my MS thesis). For those who do not know, "Id" was developed at MIT, and it is an incrementally compiled, non-strict, parallel programming language with ML-style type inference system, NICE syntax, pattern matching, and what have you. It is unclear to me why ML's top-level script was chosen not to incorporate dynamic linking. The only reason I can think of is really historical, that it started as a Meta-language for LCF, and its designers never though it would be used in interactive sessions as a real programming language which it has now grown up to be. I believe they thought all that would be required of this language was to construct program like proofs. There, it was obvious to keep things clean and simple by disallowing any incrementality and progamming language issues such as dynamic linking and editor flexibility. Cheers, Shail Aditya. shail@abp.lcs.mit.edu.
Re: Help needed with behaviour of SML
Author: Raul Rockwell
Date: Sat, 04 May 1991 17:48
Date: Sat, 04 May 1991 17:48
31 lines
1820 bytes
1820 bytes
Shail Aditya Gupta writes:
> ML's interactive script can be viewed ... with each statement being
> defined in the lexical scope of all the previous ones. If you view
> it this way ... it is logical and reasonable that the second
> definition of "a" shadows the first, but the first had been "closed
> over" in the lexical closure environment of the function "b", which
> can never be destroyed, only further shadowed...
Chris Dollin writes:
> The ML definition is fine for batch use, but for incremental
> development it's a pigs trotter.
> [*Why* is ML like this? Because it's a functional language, ie, it
> has no assignment, so values don't change. Apart, of course, from
> arrays, and references. Pah.]
triple pah!
(1) dynamic shadowing is just another name for changing values
(2) you shouldn't be able to re-assign values in a constant array (can
you??)
(3) if you want to change a value referred to from a function, you
probably ought to use a reference of some sort :-)
Raul Rockwell
Disclaimer: I'm a J person, not an ML person. I speak with a mild
ignorance of the mechanics of ML.
Re: Help needed with behaviour of SML (its interactive system)
Author: Wolfgang Grieskamp
Date: Sat, 04 May 1991 21:36
Date: Sat, 04 May 1991 21:36
25 lines
1728 bytes
1728 bytes
kers@hplb.hpl.hp.com (Chris Dollin) writes: >Here's another one. SML is an interactive incremental development language. >This means that when you find an error in a function definition, all you need >to do is to redefine the function and .... >Funny, this useful feature of interactive langauges seems to have gone wrong. >I'll just have to load all the code I've compiled since then. Exactly. Or is there someone working professional with SML who takes advantage of the interactive system? Personal (relatively little) experiences with the SML environment is that one soon writes batch files to work around it. This is irritating, since the design of the language is highly based on this "interactive" window dressing. It seems in principal that the functional and incremental development paradigms do no coincide well. But a meta language level which manages the version problem may close the gap. -- Wolfgang Grieskamp wg@opal.cs.tu-berlin.de tub!tubopal!wg wg%opal@DB0TUI11.BITNET
Re: Help needed with behaviour of SML (its interactive system)
Author: Thomas M. Breuel
Date: Mon, 06 May 1991 01:54
Date: Mon, 06 May 1991 01:54
31 lines
2314 bytes
2314 bytes
[lots of articles complaining about the fact that you can't change top-level bindings in ML] For example, wg@opal.cs.tu-berlin.de writes: Or is there someone working professional with SML who takes advantage of the interactive system? Personal (relatively little) experiences with the SML environment is that one soon writes batch files to work around it. I use SML interactively: source files in one (Emacs) window, SML in another window. I usually have one source file in which I write and debug new functions, and, eventually, they get wrapped up into a new module. Working this way, I usually only have to recompile the function I'm currently debugging (C-c C-c). If I have to fix older functions, I simply recompile the whole file (C-c C-u), or recompile them in the right order. This is not very different from CommonLisp development. I like the behavior of the SML top-level. I think any attempt at allowing the user to change the binding, or, worse yet, type of an already existing binding, would introduce lots of complications and make the top-level much harder to understand. It would also keep the compiler from making lots of optimizations that it currently can make. If recompilation speed really turns out to be an issue, an implementation of SML could, within the current language semantics, record dependencies during the first compilation and avoid recompilation of unchanged and independent values even if you just told it "compile everything". Better compilers, not worse semantics, are the answer to this issue.
Re: Help needed with behaviour of SML
Author: Nico Verwer
Date: Mon, 06 May 1991 14:16
Date: Mon, 06 May 1991 14:16
38 lines
2608 bytes
2608 bytes
In <KERS.91May2084808@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes:
> > Why does it do it like this.. Why doesn't it look up at the current
> > value of the variable 'a'...?
>
>Funny, this useful feature of interactive langauges seems to have gone wrong.
>I'll just have to load all the code I've compiled since then. I wonder what
>modules that covers?
>The ML definition is fine for batch use, but for incremental development it's a
>pigs trotter.
No, it is very fortunate that ML does NOT have "dynamic scope rules". One
point has been made before, i.e. type safety.
But even if the system would enforce some form of type safety, then still the
ML way of top level definitions is preferable, and I wished TeX would work
this way!
To illustrate this, I shall not give an example in TeX, but in functional
language style.
Suppose we have a functional language with a "standard prelude", which groups
several useful functions, like sin, cos, tan, etcetera.
I am writing a 3-D space invader game, using a function library which maps 3-D
objects onto the 2-D display. This library uses functions like sin and cos.
Somewhere in this program I define functions
sin (for "show invader number") and
cos (for "crash orbital ship").
My program will not work, because the math library will now use these
functions instead of the well-known trigonometric functions. Probably, in this
case I will soon find the error, but similar errors can be very hard to find.
I think this `feature' is one of the worst of TeX. It won't allow me to define
my own \ifx or \def, because the old definitions will be superseded by these.
(Try \renewcommand{\def}{...} in LaTeX. It generates an error which is not
easy to understand for the LaTeX novice.)
--
Nico Verwer | nico@cs.ruu.nl
Dept. of Computer Science, University of Utrecht | phone: +31 30 533921
p.o. box 80.089, 3508 TB Utrecht, The Netherlands | fax: +31 30 513791
Re: Help needed with behaviour of SML
Author: Dave Berry
Date: Mon, 06 May 1991 16:06
Date: Mon, 06 May 1991 16:06
33 lines
2377 bytes
2377 bytes
In article <KERS.91May2084808@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes: > >SML is an interactive incremental development language. This means that >when you find an error in a function definition, all you need to do is to >redefine the function and .... ML was developed as a language for manipulating values interactively. The original ML let you manipulate theorems. Later versions let you manipulate any values, such as windows or trees. ALthough ML also lets you test code incrementally, I've always felt that this was a secondary goal (I may be wrong, of course; I can't read the designers' minds). Code development in ML is a big improvement over a batch language, even with a raw environment. You can test any function interactively, and you can redefine leaf functions easily. Redefining non-leaf functions isn't as convenient if you're just presented with the raw language, but it's fairly easy to write decent programming environments to do everything automatically. Even a make system is a great help. A good environment would just recompile and re-link the changed module, without recompiling all intermediate modules (there is at least one firm developing such an environment). If I were designing an ML-like language, I would probably ban redeclaration altogether. I'd add a renaming scheme to the module system to take care of name clashes, and force people to use references if they wanted to change the value bound to a variable. (I'd also add automatic dereferencing to prevent this becoming cumbersome). Dave. -- Dave Berry, LFCS, Edinburgh Uni. db%lfcs.ed.ac.uk@nsfnet-relay.ac.uk "So they gave him a general anaesthetic and cleaned him with Swarfega."
Re: Re: Help needed with behaviour of SML (its interactive system)
Author: Chris Dollin
Date: Fri, 10 May 1991 08:29
Date: Fri, 10 May 1991 08:29
35 lines
2642 bytes
2642 bytes
Following my message that rubbishes MLs ``incremental'' compilation, a couple of responses that I want to address ... Nico Verwer says: No, it is very fortunate that ML does NOT have "dynamic scope rules". One point has been made before, i.e. type safety. But even if the system would enforce some form of type safety ... It's not dynamic scope (which is to do with rebinding *within new scopes*. Clearly if the new definition does not ascribe the same type as the old one, the inconsistency must be resolved some way; for example, the definition could be disallowed (yuk) or a new variable could be created (and the old one assigned a value such as "\x. error 'obsolete function called", and maybe all using functions tagged as obsolete). Clearly redefining "sin" (Nico's later example) would be a Bad Thing. This just means that we need some way of annotating those names no longer available for redefinition - no big deal. Someone suggested that we needed ``better tools, not worse semantics'', to solve the problem of rebuilding after a change on which lots of things depend. Well, I can see the point in that, but it's a matter of opinion as to whether the semantics is ``worse''; and solving the problem by throwing CPU cycles at it seems to me to be the wrong approach. First, I'll bet that the time taken will become appreciable quite quickly; second, those are *my* CPU cycles you're using; I might want to spend them on something else at the same time (maybe I've got another system building in the background; perhaps I'm also waiting for a chess program to deliver it's next move; maybe I have a fancy version of xfish I'd not like slowed down; etc). -- Regards, Kers. | "You're better off not dreaming of the things to come; Caravan: | Dreams are always ending far too soon."
Re: Help needed with behaviour of SML (its interactive system)
Author: Thomas M. Breuel
Date: Tue, 14 May 1991 08:20
Date: Tue, 14 May 1991 08:20
52 lines
3363 bytes
3363 bytes
In article <KERS.91May10092912@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes:
Clearly redefining "sin" (Nico's later example) would be a Bad Thing. This just
means that we need some way of annotating those names no longer available for
redefinition - no big deal.
Someone suggested that we needed ``better tools, not worse semantics'', to
solve the problem of rebuilding after a change on which lots of things depend.
Well, I can see the point in that, but it's a matter of opinion as to whether
the semantics is ``worse''; and solving the problem by throwing CPU cycles at
it seems to me to be the wrong approach.
"Better tools" does not mean "throwing CPU cycles at the problem".
You are proposing that I can say something like:
redefine fun f x = ... ;
But I think this is a bad idea. I don't know about you, but I have a
hard time keeping track of the implications of redefinitions like
this.
Ultimately, what I expect of a good SML development environment is
that I edit some value "x" deep inside some structure, tell the system
that I'm through editing my sources, switch to the SML toplevel, and
find that the internal state of the SML system reflects the new state
of my sources, in particular the new value of "x". In order for this
to happen quickly enough, the system will have to generate commands
like "redefine" internally, but I never want to see them.
The "make" systems that float around are a start. Their major
shortcomings is that they don't infer dependencies automatically
(dependencies should be inferred, stored, and updated as I first load
and then modify my sources). Also, they only work at a file level,
not a definition level.
It may also be possible to hack something up analogous to "make" that
relies on file modification dates, signatures for blocks of text
inside files, recording of information during load, etc., so that even
without a tight integration between editor and SML toplevel I may get
reasonable performance on recompilation. That is, when I tell the
system something like 'use "file.sml";', the system could use
knowledge of the previous contents of "file.sml" (and the contents and
modification dates of files "use"d by "file.sml") to infer what
"redefine" commands need to be issued in what sequence and come close
to minimal recompilation.
Again, I think making something like "redefine" visible to the user is
a bad idea. I certainly don't want to have to bother with it, and
implementors would just use it as an excuse not to have to come up with
decent development environments.
Thomas.
Re: Help needed with behaviour of SML (its interactive system)
Author: Nico Verwer
Date: Thu, 16 May 1991 13:03
Date: Thu, 16 May 1991 13:03
42 lines
2866 bytes
2866 bytes
In <KERS.91May10092912@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes:
>Clearly if the new definition does not ascribe the same type as the old one,
>the inconsistency must be resolved some way; for example, the definition could
>be disallowed (yuk) or a new variable could be created (and the old one
>assigned a value such as "\x. error 'obsolete function called", and maybe all
>using functions tagged as obsolete).
Disallowing the definition is obviously not a good idea. Discarding the old
binding is better, but static scoping (like ML does) improves on this, by not
binding the old definition to "\x. error", but hiding it.
>Clearly redefining "sin" (Nico's later example) would be a Bad Thing. This just
>means that we need some way of annotating those names no longer available for
>redefinition - no big deal.
But sometimes I really want to redefine a definition. One of the features
of teX (which supports dynamic scoping through macro substitution) which
drives me crazy is that I sometimes cannot define a command by
\newcommand{\name}{body}
because it already exists --- it is annotated as "no longer available for
definition".
I then have to use \renewcommand{\name}{body}
but that is potentially dangerous.
Suppose I am a novice LaTeX user, writing a paper on scoping in ML, and I
want to define a command \let for typesetting programs which use
let ... = ... in ... ;
LaTeX complains when the I say \newcommand{\let}{...}.
Now I know much about ML (remember this is only an example!) but little
about TeX (he I don't even know about the difference between TeX/LaTeX).
I therefore say \renewcommand{\let}{...}, with disastrous results.
The problem is that TeX uses its own \let, which I don't need, and that I
want to use my own \let, and I don't want to give it another name.
Marking the old \let is just as bad as \renewcommand-ing it.
The only solution here really is static scoping!
There is a discussion about scoping in TeX on comp.text.tex at the moment.
If only TeX would scope like ML...
--
Nico Verwer | nico@cs.ruu.nl
Dept. of Computer Science, University of Utrecht | phone: +31 30 533921
p.o. box 80.089, 3508 TB Utrecht, The Netherlands | fax: +31 30 513791
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads