Common Lisp Unbound Variable - lisp

Is it possible to use an uninitialized variable as a function argument? For an assignment, I have to use the CLOS to write a semantic network system, and my professor included a test function to test our output, and one of them specifies:
(print (def-concept Human)),
which implies passing the argument Human to the function def-concept. When running this test function, I cannot get away from the error (in Allegro CL):
Error: Attempt to take the value of the unbound variableHUMAN'.`
As this is the first function in the test, there is no initializing of any variables before this. Is there any way to get around passing an uninitialized variable as an argument of a function?
Thanks in advance.

It is not possible to use an unitialized value as a function argument in a regular Common Lisp function call. Common Lisp uses eager evaluation: argument expressions are reduced to their values before the function call takes place.
I suspect maybe you don't exactly understand the structure of the homework assignment.
If def-concept is a function which expects a value, and human is not defined, you simply cannot test that function.
Perhaps you are expected to define the variable human and then load the file containing (print (def-concept human)).
Just because there is nothing prior to that form in the same file doesn't mean that no prior evaluation is possible. Other files can be loaded before that file, or forms evaluated in the listener.

Related

Usefulness of let?

Is the distinction between the 3 different let forms (as in Scheme's let, let*, and letrec) useful in practice?
I am current in the midst of developing a lisp-style language that does current support all 3 forms, yet I have found:
regular "let" is the most inefficient form, effectively having to translate to an immediately called lambda form and the instructions generated are nearly identical. Additionally, I haven't found myself needing this form very often.
let* (sequential binding) seems to be the most practically useful and most often used. This form can be translated to a sequence of nested "lets", each environment storing a single variable. But this again is highly inefficient, wasting space and lookup time.
letrec (recursive binding) can be efficiently implemented, given that no initializer expression refers to an unbound variable. Typically the case is that all initializers are lambda expressions and the above is true.
The question is: since letrec can be efficiently implemented and also subsumes the behavior of let*, regular let is not often used and can be converted to a lambda form with no great loss of efficiency, why not make default "let" have the behavior of the current "letrec" and be rid of the original "let"?
This [let*] form can be translated to a sequence of nested "lets", each environment storing a single variable. But this again is highly inefficient, wasting space and lookup time.
While what you are saying here is not incorrect, in fact there is no need for such a transformation. A compiling strategy for the simple let can handle the semantics of let* with just simple modifications (possibly supporting both with just a flag passed to common code).
let* just alters the scoping rules, which are settled at compile time; it's mostly a matter of which compile-time environment object is used when compiling a given variable init form.
A compiler can use a single environment object for the sequential bindings of a let*, and destructively update it as it compiles the variable init forms, so that each successive init form sees a more and more extended version of that environment which contains more and more variables. At the end of that, the complete environment is available with all the variables, for doing the code generation for generating the frame and whatnot.
One issue to watch out for is that a flat environment representation for let* means that lexical closures captured during the variable binding phase can capture future variables which are lexically invisible to them:
(let* ((past 42)
(present (lambda () (do-something-with past)))
(future (construct-huge-cumbersome-object)))
...))
If there is a single run-time environment object here containing the compiled versions of the variables past, present and future, then it means that the lambda must capture that environment. Which means that although ostensibly the lambda "sees" only the past variable, because future is not in scope, it has de facto captured future.
Thus, garbage collection will consider the huge-cumbersome-object to be reachable for as long as the lambda remains reachable.
There are ways to address this, like accompanying the environmental reference emanating from the lambda with some kind of frame index which says, "I'm only referencing part of the environment vector up to index 13". Then when the garbage collector traverses this fenced reference, it will only mark the indicated part of the environment vector: cells 0 to 13.
Anyway, about whether to implement both let and let*. I suspect if Lisp were being "green field" designed from scratch today, many designers would like reach for the sequentially binding version to be called let. The parallel construct would be the one available under the special name let*. The situations when you actually need let to be parallel are fewer. For instance, let allows us to re-bind a pair of variable symbols such that their contents appear exchanged; but this is rarely something that comes up in application programming. In some programming language cultures, variable shadowing is frowned up on entirely; GNU C has a -Wshadow warning against it, for instance.
Note how in ANSI Common Lisp, which has let and let*, the optional parameters of a function behave sequentially, like let*, and this is the only binding strategy supported! So that is to say:
(lambda (required &optional opt1 (opt2 opt1)) ...)
Here the value of opt2 is defaulted from whatever the value of opt1 is at the time of the call. The initialization expression of opt2 has the opt1 parameter in scope.
Also, in the same Lisp dialect, the regular setf is sequential; if you want parallel assignment you must use psetf, which is the longer name of the two.
Common Lisp already shows evidence of design decisions more recent than let tend to favor sequential operation, and designate the parallel as the extraordinary variant.
Think of metaprogramming. If your default let will sequentially create nested scopes, you'll have to make sure that none of the initialiser expressions are referring to the names from the wrong scopes. You have such a guarantee with a regular let. Control over name scoping is very important when you're generating code.
Letrec is even worse, it's introducing a very complicated scope rules that cannot be easily reasoned with.

Stata and global variables

I am working with Stata.
I have a variable called graduate_secondary.
I generate a global variable called outcome, because eventually I will use another outcome.
Now I want to replace the variable graduate if a condition relative to global is met, but I get an error:
My code is:
global outcome "graduate_secondary"
gen graduate=.
replace graduate=1 if graduate_primary==1 & `outcome'==1
But i receive the symbol ==1 invalid name.
Does anyone know why?
Something along those lines might work (using a reproducible example):
sysuse auto, clear
global outcome "rep78"
gen graduate=.
replace graduate=1 if mpg==22 & $outcome==3
(2 real changes made)
In your example, just use
replace graduate=1 if graduate_primary==1 & $outcome==1
would work.
Another solution is to replace global outcome "graduate_secondary" with local outcome "graduate_secondary".
Stata has two types of macros: global, which are accessed with a $, and local, which are accessed with single quotes `' around the name -- as you did in your original code.
You get an error message because a local by the name of outcome has no value assigned to it in your workspace. By design, this will not itself produce an error but instead will the reference to the macro will evaluate as a blank value. You can see the result of evaluating macro references when you type them by using display as follows. You can also see all of the macros in your workspace with macro dir (the locals start with an underscore):
display `outcome'
display $outcome
Here is a blog post about using macros in Stata. In general, I only use global macros when I have to pass something between multiple routines, but this seems like a good use case for locals.

What is the function "defs" in Lisp?

In the "Dictio" file, located at the link "Text-only console version" of this site, I've noticed a Lisp command (?) called defs.
I assume that this is something similar to defun, but am unable to find any information on what defs does; is it used to define a function, or maybe a variable? I am looking to reproduce this code using modern techniques and it would help to know the purpose of defs.
The defs calls seem to also include more than a name before the arguments (I would expect it to read (defs name () body).
Looking at the first function in the list, there appears to be more included in this "function definition" [the word 'features' specifically] and in the third function, there is ['semantics'] included after what appears to be the name of the function (before the arguments).
DEFS is defined by the software in the file SYSCOM.
It is a FEXPR, which is a function which gets the arguments unevaluated. Common Lisp has no such feature. It uses macros instead.
Example use:
(DEFS \#COLOR
FEXPR (LAMBDA (A)
(EVAL (SUBST (CAR A)
'COLOR
'(OBJECT
(MARKERS\: (\#PHYSOB COLOR)
PROCEDURE\: ((\#COLOR *** COLOR)))))))
PRIORITY 192.
SYS (\#PROPERTY))
Here you have a symbol #COLOR. It gets a function (actually a FEXPR) defined under this name. Also it puts a PRIORITY and SYS onto the property list of the symbol. Thus DEFS is used to define symbols with functions and properties in one defining form.

what is the difference between 'define as' to 'define as computed' in specman?

The difference between the two is not so clear from the Cadence documentation.
Could someone please elaborate on the difference between the two?
A define as macro is just a plain old macro that you probably know from other programming languages. It just means that at some select locations in the macro code you can substitute your own code.
A define as computed macro allows you to construct your output code programmatically, by using control flow statements (if, for, etc.). It acts kind of like a function that returns a string, with the return value being the code that will be inserted in its place by the pre-processor.
With both define as and define as computed macros you define a new syntactic construct of a given syntactic category (for example, <statement> or <action>), and you implement the replacement code that replaces a construct matching the macro match expression (or pattern).
In both cases the macro match expression can have syntactic arguments that are used inside the replacement code and are substituted with the actual code strings used in the matched code.
The difference is that with a define as macro the replacement code is just written in the macro body.
With a define as computed macro you write a procedural code that computes the desired replacement code text and returns it as a string. It's effectively a method that returns string, you can even use the result keyword to assign the resulting string, just like in any e method.
A define as computed macro is useful when the replacement code is not fixed, and can be different depending on the exact macro argument values or even semantic context (for example, in some cases a reflection query can be used to decide on the exact replacement code).
(But it's important to remember that even define as computed macros are executed during compilation and not at run time, so they cannot query actual run time values of fields or variables to decide on the resulting replacement code).
Here are some important differences between the two macro kinds.
A define as macro is more readable and usually easier to write. You just write down the code that you want to be created.
Define as computed macros are stronger. Everything that can be implemented with define as, can also be implemented with define as computed, but not vice versa. When the replacement code is not fixed, define as is not sufficient.
A define as macro can be used immediately after its definition. If the construct it introduces is used in the statement just following the macro, it will already be matched. A define as computed macro can only be used in the next file, and is not usable in the same file in which the macro is defined.

what's the fundamental differences of variables and symbols?

I'm rather confused about this.
And what's their relationship(e.g., how one can be used in the context of the other)? Much thanks!!
Is this what you are looking for ?
A symbol is basically just an object with four fields:
a name (a string),
a value (some Lisp object),
a function (some Lisp object), and
a property list (usually a list of alternating keyword/value pairs).
What makes symbols special is that there is usually only one symbol with a given name, and the symbol is referred to by name. This makes a symbol a convenient way of calling up data by name, i.e. of implementing variables. (The variable's value is stored in the value slot.)
Similarly, functions are referenced by name, and the definition of the function is stored in a symbol's function slot. This means that there can be a distinct function and variable with the same name.
The property list is used as a more general mechanism of associating additional values with particular names, and once again the namespace is independent of the function and variable namespaces.
Simply put, a variable is a binding between a symbol and a value. The symbol is the name of the variable. When a bound symbol (ie. a variable name) is evaluated, the variable value is returned,
You can also use symbols which are not variables, ie. names which are not bound to a value. You cannot evaluate an unbound symbol though.
In Lisp-2's a symbol can be bound to both a value and a function at the same time, The context defines if the result of evaluating the symbol is the value or the function.
The concept of symbols is a little bit hard to understand. (Even I'm not sure I got it :) )
You can look at symbols as special variables which behave like constants. There is only one instance in memory, no matter how often you used it.
The benefits are conserving memory and one can see if a value is used in a constant-like manner. (Improves code readability)
You can do similar things in C/C++ with typdef, in Java with static final or in Delphi/Pascal/VB with const, but be careful, in those and many other languages "symbol" means something different.