From: axtens on
G'day everyone

Is this an example of a closure or just a trick with Eval?

Kind regards,
Bruce

---
option explicit
class closure

private composition

sub compose( f1, f2 )
composition = f2 & "(" & f1 & "(p1))"
end sub

public default function apply( p1 )
apply = eval( composition )
end function

public property get formula
formula = composition
end property

end class

dim c
set c = new closure

c.compose "ucase", "lcase"
wscript.echo c.formula
wscript.echo c("dog")

c.compose "log", "exp"
wscript.echo c.formula
wscript.echo c(12.3)

function inc( n )
inc = n + 1
end function

c.compose "inc", "inc"
wscript.echo c.formula
wscript.echo c(12.3)

function twice( n )
twice = n * 2
end function

c.compose "twice", "inc"
wscript.echo c.formula
wscript.echo c(12.3)

Output:

lcase(ucase(p1))
dog
exp(log(p1))
12.3
inc(inc(p1))
14.3
inc(twice(p1))
25.6
From: mayayana on
I don't really understand your post, but I'm
curious. :) I had to look up Closure. I'd never
heard of it. A closure is an independent function,
within a function, in the scope of that function?
I don't see the point of that. It seems like a
very poor design to me.

I've also never understood the use of Eval.
According to the help, the VBS version evaluates
an operation. The WSH v. 5.6 help says that Eval
can also run a function, but says that's only in
javascript. Yet it works for me in VBS. But I don't
see the point of that, either. So there are two
different Evals and I don't see any reason for either
of them to exist. The help says that the Eval function
is used to avoid ambiguity in VBS, but the ambiguity
they describe is not really ambiguity. Two syntaxes
produce two results, that's all.

x = y ' assigns y to x
If x = y then ' compares x and y.

I don't need Eval to clear that up, so I don't get
the purpose of it.

'--------------------------------

'-- These two do the same thing:

x = 4
y = 5
if Not Eval(x = y) then msgbox "False"
if x <> y then Msgbox "False"

'---------------------------------

'-- Likewise, these two do the same thing:

x = 4
y = 5

MsgBox Eval(xy)
MsgBox xy

Function xy()
xy = x + y
End function
'---------------------------

You seem to be using Eval on a variable:

apply = Eval(composition)

I'm surprised to find that also works. So there
seem to be 3 distinct uses of Eval. But all 3
seem to be superfluous. I don't get it. What's the
difference between these two?

msgbox Eval(composition)
and
msgbox composition


And why would the simple calling of another function
from within a function be a Closure? And why do you need
a class to demonstrate your example? Most of all I'm
curious about why anyone would ever want to use a
Closure....whether maybe there's some advantage that
I'm not seeing.

So I guess I don't get any reason at all for Eval or
for a Closure. But I'm keeping an open mind because
someone took the trouble to think them up. :)

>
> Is this an example of a closure or just a trick with Eval?
>
> Kind regards,
> Bruce
>
> ---
> option explicit
> class closure
>
> private composition
>
> sub compose( f1, f2 )
> composition = f2 & "(" & f1 & "(p1))"
> end sub
>
> public default function apply( p1 )
> apply = eval( composition )
> end function
>
> public property get formula
> formula = composition
> end property
>
> end class
>
> dim c
> set c = new closure
>
> c.compose "ucase", "lcase"
> wscript.echo c.formula
> wscript.echo c("dog")
>
> c.compose "log", "exp"
> wscript.echo c.formula
> wscript.echo c(12.3)
>
> function inc( n )
> inc = n + 1
> end function
>
> c.compose "inc", "inc"
> wscript.echo c.formula
> wscript.echo c(12.3)
>
> function twice( n )
> twice = n * 2
> end function
>
> c.compose "twice", "inc"
> wscript.echo c.formula
> wscript.echo c(12.3)
>
> Output:
>
> lcase(ucase(p1))
> dog
> exp(log(p1))
> 12.3
> inc(inc(p1))
> 14.3
> inc(twice(p1))
> 25.6


From: ekkehard.horner on
mayayana schrieb:
> I don't really understand your post, but I'm
> curious. :) I had to look up Closure. I'd never
> heard of it. A closure is an independent function,
> within a function, in the scope of that function?

No, a closure is a function that retains/keeps (part of) the
context it was created in. When such a function is called later,
this context can be used. In that way you get a tight association
between data (information) and behavior (code) - a closure is
like an object with just one method.

> I don't see the point of that. [...]

"closure" belongs to the paradigm of Functional Programming; if
you look up that, you'll see that closures are an important item
in that context.

> [...] It seems like a very poor design to me.

Then you are wrong.

>
> I've also never understood the use of Eval.
> According to the help, the VBS version evaluates
> an operation. [...]

The correct quote is:

Eval *Function*
Evaluates an *expression* and *returns* the result

> [...] The WSH v. 5.6 help says that Eval
> can also run a function, but says that's only in
> javascript. Yet it works for me in VBS.

I doubt that the JScript

eval *method*
*Evaluates* JScript code and *executes* it

works in VBScript.

> [...] But I don't
> see the point of that, either. [...]

So what?

> [...] So there are two
> different Evals and I don't see any reason for either
> of them to exist. [...]

No, there is just one Eval *function* in VBScript, that takes a string
containing a valid VBScript expression and returns the value of that
expression. That other languages have functions/methods with the same
name is irrelevant.

> [...] The help says that the Eval function
> is used to avoid ambiguity in VBS, but the ambiguity
> they describe is not really ambiguity. Two syntaxes
> produce two results, that's all.

The decision to use "=" both as assigment and as comparison operator
creates the ambiguity that "a = b" can be seen as an expression evaluating
to True or False depending on the content of the variables or an
assignment of the content of b to a. That's why VBScript has Eval to
evaluate expressions and Execute(Global) to execute statements - see:

>> nA = 47
>> nB = 11
>> WScript.Echo "nA:", nA, "nB:", nB
>> sExpr = "nA = nB"
>> bRes = EVal( sExpr )
>> WScript.Echo sExpr, "=>", CStr( bRes )
>>
nA: 47 nB: 11
nA = nB => Falsch
>> sStmt = sExpr
>> Execute sStmt
>> WScript.Echo "nA:", nA, "nB:", nB
>> bRes = EVal( sExpr )
>> WScript.Echo sExpr, "=>", CStr( bRes )
>>
nA: 11 nB: 11
nA = nB => Wahr
>>

(The JScript eval method can do both, because an expression like "a == b"
can't be seen as a assignment statement like "a = b")

[...]
From: mayayana on

> No, a closure is a function that retains/keeps (part of) the
> context it was created in. When such a function is called later,
> this context can be used. In that way you get a tight association
> between data (information) and behavior (code) - a closure is
> like an object with just one method.
>

Your description sounds
like a Static variable in VB, which holds its
assigned value between calls. But a static
variable is not functionally different from a
global variable. It just has a scope local to
the function it's in.
Is a Closure basically a function within
a function that has a static variable?

> I doubt that the JScript
>
> eval *method*
> *Evaluates* JScript code and *executes* it
>
> works in VBScript.
>

I think you're right. I see that I misunderstood
that. The VBS Eval can evaluate a statement,
a function call, or a variable, but apparently can't
execute code.

> The decision to use "=" both as assigment and as comparison operator
> creates the ambiguity that "a = b" can be seen as an expression evaluating
> to True or False depending on the content of the variables or an
> assignment of the content of b to a. That's why VBScript has Eval to
> evaluate expressions

I understood that, but as I posted before it's
a superfluous function that makes no sense.
There's no ambiguity in context.
You used this relatively complex code:

sExpr = "nA = nB"
bRes = EVal( sExpr )
WScript.Echo sExpr, "=>", CStr( bRes )

But these 3 variations all do the same
thing in an easier, more readable way:

If nA <> nB Then MsgBox "False"

MsgBox na = nb

bRes = nA = nB
MsgBox bRes


If there's no better usage than what you used
as an example then personally I would conclude
that there is, indeed, no purpose to Eval in VBS.


From: Bob Barrows on
mayayana wrote:
>> No, a closure is a function that retains/keeps (part of) the
>> context it was created in. When such a function is called later,
>> this context can be used. In that way you get a tight association
>> between data (information) and behavior (code) - a closure is
>> like an object with just one method.
>>
>
> Your description sounds
> like a Static variable in VB, which holds its
> assigned value between calls. But a static
> variable is not functionally different from a
> global variable. It just has a scope local to
> the function it's in.

Every discussion of closures I've previously seen centered on how they
were typically unintentionally created, as well as the adverse effects
when they are created (memory leaks, IIRC). There was little discussion
as to their desirability or usefulness. I will need to research what
Ekkehard referred to.


> Is a Closure basically a function within
> a function that has a static variable?
>
>> I doubt that the JScript
>>
>> eval *method*
>> *Evaluates* JScript code and *executes* it
>>
>> works in VBScript.
>>
>
> I think you're right. I see that I misunderstood
> that. The VBS Eval can evaluate a statement,
> a function call, or a variable, but apparently can't
> execute code.

Right, that's what Execute is for
>
>
> If there's no better usage than what you used
> as an example then personally I would conclude
> that there is, indeed, no purpose to Eval in VBS.

I suppose you've read what Eric Lippert has had to say about this? ;-)

--
HTH,
Bob Barrows