Re: letrec/named let
- To: mathgroup at smc.vnet.net
- Subject: [mg56751] Re: letrec/named let
- From: Peter Pein <petsie at dordos.net>
- Date: Thu, 5 May 2005 06:01:32 -0400 (EDT)
- References: <d59kvq$6f9$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Daniel Roy wrote:
> hi. i'm a lisper/schemer and i'm working with mathematica. i
> appreciate the lisp-like nature of mathematica but i can't seem to
> easily replicate some of the functionality i like which is forcing me to
> write ugly side-effect code.
>
> for instance, how do you do the equivalent of a "named let" in
> mathematica (NOTE! I know i can take the max of a list, this is just a
> simple example of a named let)
>
> (define (max-of-list lst)
> (let loop ((lst (cdr lst))
> (best (car lst)))
> (if (null? lst)
> best
> (loop (cdr lst)
> (if (> (car lst) best)
> (car lst)
> best)))))
>
> (max-of-list '(1 2 3 4 5 2))
>
>>5
>
Translating this one to one into Mathematica would yield something
awkward as:
maxOfList[lst_] := Module[{loop},
loop = Function[{rst, best},
If[rst == {},
best,
loop[Rest[rst], If[First[rst] > best, First[rst], best]]]];
loop[Rest[lst], First[lst]]
]
maxOfList[{1, 2, 3, 4, 5, 2}]
>5
This function has no side effects (despite wasting time ;-) ).
>
> Here is a mathematica function to compress a sequence numerically.
> here is one attempt using functions where i pass the function to
> itself... there has to be a better way
>
> CompressNumericalSequence[S_] := Module[
> {C = Function[{C, R, i},
> If[i < Max[R],
> If[Length[Position[R, i]] == 0,
> C[C, (If[# > i, # - 1, #]) & /@ R, i],
> C[C, R, i + 1]],
> R]]},
> C[C, S, 1]];
>
> CompressNumericalSequence[{10, 2, 4, 7, 8}]
> {5, 1, 2, 3, 4}
You always give C as first argument; so it is superflous.
Pleas note, that C is reserved:
"C[i] is the default form for the ith parameter or constant
generated in representing the results of various symbolic
computations."
CompressNumericalSequence[S_]:=
Module[{fC},
fC=Function[{R,i},
If[i<Max[R],
If[Length[Position[R,i]]==0,
fC[(If[#>i,#-1,#])&/@R,i],
fC[R,i+1]],R]];
fC[S,1]];
but this will fail for big numbers unless you set $IterationLimit
appropriate. Hence,
CNS[lst_] := lst /. (Thread[#1 -> Ordering[Ordering[#1]]] & )[
Module[{f}, f[x_] := (f[x] = Sequence[]; x); f /@ lst]];
or even better
CNS[lst_] := Module[{tmp = First /@ Split[Sort[lst]]},
Flatten[(Position[tmp, #1] & ) /@ lst]]
would do the task more reliable (and much more faster).
>
> Also, is it possible to do letrec in mathematica? (essentially, i know
> i can do recursive function declarations at the top level... my question
> is whether i can do them at lower levels?)...
>
> thanks, dan
>
If i understand this (german) article
(https://www.linux-magazin.de/Artikel/ausgabe/2000/12/Lisp/Lisp.html)
correctly, letrec is just another form of a "named lambda". This is what
the "fC=Function[{},...]" above does. Or am I wrong? The Mathematica
help topic "Function" might be of interest.
Regards,
Peter
--
Peter Pein
Berlin