How can I reliably compare two Symbols for equality in scala macro or when using reflection? Is it guaranteed that when two Symbol objects represent the same symbol (the same class, the same local value or variable, etc.) they will be equal in terms of == operator?
What do I need this for? I have a Tree in a macro that represents some expression that may reference some local value. I want to transform this tree and replace all references to this local value with references to some other value.
Yes, == (or eq, the reference equality comparison, which does the same in this case) is the way to go to compare symbols.
Related
The array is expecting a literal value
set chrom [forage_min forage_rate share_min share_rate mating_treshold]
print chrom
How can I handle it? I really don't understand arrays in Netlogo.
(You speak of "arrays" in your question, but I think you mean "lists". It is possible to use arrays in NetLogo via the array extension, but unless you have very specific needs, that's probably not what you want. So, assuming that you are trying to create a list:)
The square bracket syntax for declaring lists only works with "literal" values, e.g., raw strings or numbers. If you want to build a list out of variables or more complex expressions, you need to use the list primitive. In your case, that would be something like:
set chrom (list forage_min forage_rate share_min share_rate mating_treshold)
I would encourage you to read the Lists section of the NetLogo programming guide.
I have a Symbol and want to check if it's visible at the point of macro expansion or shadowed (e.g. by a local variable), so that splicing the symbol's name in the quasiquote doesn't refer to something else.
Looking at http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html, one idea would be to look at the enclosing lexical scopes and check if they contain a symbol with the same name; the problem is that I can't find a way to obtain the directly enclosing scope for the macro.
Solution based on som-snytt's reply on scala-user:
symbol.pos == c.typecheck(q"${symbol.name.toTermName}").symbol.pos
(I had to compare positions, because in one of my tests the symbols weren't equal despite having the same name, owner and position.)
I'd like to know how I can distinguish between 'value' and 'expression'.
In computer science, a value is an expression which cannot be
evaluated any further (a normal form).[1] The members of a type are
the values of that type.[1] For example, the expression 1 + 2 is not a
value as it can be reduced to the expression 3. This expression cannot
be reduced any further (and is a member of the type Nat) and therefore
is a value.
I found a statement above from the url below:
https://en.wikipedia.org/wiki/Value_(computer_science) 2
From this statement I felt like:
I think "value" look like the "atom" in chemistry based upon the
definition of Mitchell, John C.
But someone denied this:
But, even expressions can be (represented as) values. The classic case
being an s-expression in Lisp-like languages. – user2864740
This talk is in another thread : what-is-the-value-in-1st-class-value 3
It would have been so simple if user2864740 didn't say anything. But he said so and I am confused.
Could someone explain me about this situation? or the difference that might exist in lisp like languages?
Thank you in advance!
[1] Mitchell, John C. (1996). Foundations for Programming Languages. The MIT Press.
If you don't know Lisp, read SICP and play with some Scheme implementation.
(the classic SICP book is a must read -it is a very good introductory book about programming-, so even if you know Lisp but didn't read SICP you really should read it; and it is freely available on-line.)
I strongly recommend reading C.Queinnec's Lisp In Small Pieces book, which explains how LISP interpreters or compilers expressions are designed, so cover your question is great details.
(actually your question needs an entire book to be answered, and Queinnec's book is that book)
LISP is an homoiconic language, hence s-expressions are values (but several values are not expressions, in particular closures). But most programming languages -C, Ocaml, Javascript, C++, Java, etc...- are (sadly) not homoiconic: their AST is not a value and expressions cannot manipulate ASTs natively.
BTW, the wikipedia sentence
a value is an expression which cannot be evaluated any further
is not always correct. For example, for the C language, values and expressions are different kind of beasts.
You should also read something about formal semantics of programming languages.
Also, reading Scott's Programming Language Pragmatics will give you a broader view (thru several programming languages).
A value is a datum: the machine representation of some piece of information, such as a number or character string. The datum belongs to a type which has an associated domain: as set of all possible values of that type. The value is an element of that set.
An expression is a datum which represents syntax: usually a structured datum build as an aggregate (usually a tree structure) of other values. However, an individual non-aggregated value can also be an expression.
The purpose of an expression may be to denote the computation of a value; in that situation, ANSI Common Lisp refers to an expression as a form. Not all expressions are forms. For instance in (let ((a 42))), (a 42) is an expression denoting, in the context of let, the variable a and its initializing form 42, and ((a 42)) is an expression denoting the complete list of binding specifications under that let.
If a form is evaluated, and the result is a datum similar to that form itself, then one of the two is the case: the form might be a literal (a value which evaluates to itself if it is treated as an expression) or it might be a quine: a clever form which doesn't directly yield itself as a value (the way a literal does) but cleverly calculates an object which is structurally identical to itself.
A value is not defined as an expression which is irreducible and denotes itself; that is a literal constant. A literal constant denotes a value. Values, however, exist in all contexts, such as the run-time context in which syntax is no longer relevant. When a program is running, it can instantiate values which never exist as a piece of syntax. If we evaluate (+ 2 2), there is a 4 which never appeared in the syntax as the expression 4. Therefore we cannot say that the value 4 is an expression which is irreducible; the value exists even if no such expression does.
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.
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.