🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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
#885
Author: Surendar Chandra
Date: Fri, 26 Apr 1991 20:16
27 lines
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
#886
Author: Thomas M. Breuel
Date: Sat, 27 Apr 1991 02:27
47 lines
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
#887
Author: Bennet Vance
Date: Sat, 27 Apr 1991 04:28
34 lines
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
#891
Author: Markus Freericks
Date: Sat, 27 Apr 1991 11:00
35 lines
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
#893
Author: Steve Knight
Date: Tue, 30 Apr 1991 11:02
14 lines
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
#896
Author: Chris Dollin
Date: Thu, 02 May 1991 07:48
37 lines
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)
#898
Author: Shail Aditya Gupta
Date: Sat, 04 May 1991 07:05
59 lines
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
#897
Author: Raul Rockwell
Date: Sat, 04 May 1991 17:48
31 lines
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)
#899
Author: Wolfgang Grieskamp
Date: Sat, 04 May 1991 21:36
25 lines
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)
#900
Author: Thomas M. Breuel
Date: Mon, 06 May 1991 01:54
31 lines
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
#901
Author: Nico Verwer
Date: Mon, 06 May 1991 14:16
38 lines
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
#902
Author: Dave Berry
Date: Mon, 06 May 1991 16:06
33 lines
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)
#910
Author: Chris Dollin
Date: Fri, 10 May 1991 08:29
35 lines
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)
#971
Author: Thomas M. Breuel
Date: Tue, 14 May 1991 08:20
52 lines
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)
#974
Author: Nico Verwer
Date: Thu, 16 May 1991 13:03
42 lines
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