An5Drama
An5Drama

Reputation: 567

Why can we use first-class expression in place of first-class function?

This is from this CS 61A notes about SICP p80~82 about ucblogo (a dialect of Logo, which derived from Lisp):

  1. Second, Logo has first-class expressions; you can run a list that you get as an argument.

This seems to mean data implicitly can be function for "first-class expression". That's a bit weird.

  1. WHILE implementation

Allows first-class expressions (WHILE).

...

to while :condition :action
if not run :condition [stop]
run :action
while :condition :action
end

to example :x
while [:x > 0] [print :x make "x :x-1]
end

This wouldn’t work with lexical scope, because within the procedure while we couldn’t evaluate the argument expressions, because the variable x is not bound in any environment lexically surrounding while. Dynamic scope makes the local variables of example available to while. That in turn allows first-class expressions. (That’s what Logo uses in place of first-class functions.)

"the variable x is not bound in any environment lexically surrounding while" is due to pass [:x > 0] as the quoted thing. That is said in the following

But since expressions aren’t represented as lists, the same punctuation that delimits a list also quotes it:

2.1 general special form implementation

If you wanted to write while in Scheme, basically, you’d have to make it a special form that turns into something using thunks. That is, you’d have to make

(while cond act)

turn into

(while-helper (lambda () cond) (lambda () act))

But the Logo point of view is that it’s easier for a beginning programmer to understand first-class expressions than to understand special forms and thunks.

IMHO the above means "first-class expression" (e.g. WHILE ......) means some expression which is only evaluated partly, i.e. lazy evaluation.

Q:

As this wikipedia link shows, First-class citizen (including first-class function defined in SICP) definition:

These operations typically include being passed as an argument, returned from a function, and assigned to a variable.

That has little relations with the above special usages for first-class expression. So what is first-class expression and then why can it be used "in place of first-class functions" as the notes say?

Upvotes: 1

Views: 78

Answers (2)

coredump
coredump

Reputation: 38924

The meaning of first-class expression here is that a program written in the language is able to manipulate expressions like any other data. Not only can you pass them as arguments and return them from functions, etc. you can also build arbitrary expressions from data. You can write push :list :expression etc. (I don't know the language), and later, run :list.

There is no such thing in a language like C1, where expressions are only visible by the compiler and not the runtime.

Secondly, it can be used in place of first-class functions because thanks to dynamic scoping, it is possible to execute arbitrary code at runtime using expression blocks. You do not use them exactly the same way, because functions can create closures, but they are equally useful. For example you could write a map function that applies the same expression list to a list of values.

1: in C as standardized, in practice there are ways to call compilers and loaders at runtime but that's not the point

Upvotes: 1

Barmar
Barmar

Reputation: 782166

To execute arbitrary expressions defined at run time, you need to use the eval procedure. But this is of limited utility in something like while, because it has no access to the lexical environment. It takes an environment specifier as an argument, but there's no standard way to get a specifier for the lexical environment. R7RS section 6.12 only specifies functions to get the environment of the REPL, an environment just containing bindings defined in one of the Scheme specifications, or an environment containing imported libraries.

So you can only use global variables and functions in the expression.

Upvotes: 0

Related Questions