What's (in simple terms) the difference between setting a binding (LET) and symbols (=variables) in common lisp?
Symbols and variables are two very different kinds of entities. Symbol is a name of something; variable is a container for a value. Variable can be named by a symbol.
Binding is an association between a symbol and a variable; when binding is in effect, you can refer to a variable by its name. let form creates such a binding.
(let ((a 1))) sets the value of a to 1 until the point where the closing bracket which matches the opening bracket before the let is reached, at which point a reverts to whatever it's previous value was (or becomes undefined). You often see a let in the body of a function where you require local variables which need to go out of scope at the end of the function, so you would use a let there.
(setf a 1) sets a to 1 and assumes that either a has been previously defined (whether by defparameter, defvariable or let) or that a is a new special variable that needs a value.
It's a bit more complicated than that but I'm not sure i have the lisp chops to explain it.
Related
For example, a variable is declared as TEST_VAR.
1. $TEST_VAR
2. $(TEST_VAR)
3. ${TEST_VAR}
4. $$TEST_VAR
5. $$(TEST_VAR)
6. $${TEST_VAR}
What the right way to use it in the .pro file?
Qmake is an interpretator, so it doesn't have explicit variable declarations.
Qmake's assignment operator has a form of "variable = string", so, say X = Y is interpreted as "the variable named X is assigned with a string "Y"". To produce a (string) value of a variable an operator $$ is needed: X = $$Y.
The operator $$ has two forms: $$Y and $${Y}. Both are equivalent, except the latter allows pasting variable's value with another string. For example, X = $$YZ means "X is assigned with the value of a variable named YZ", while X = $${Y}Z means "X is assigned with the value of a variable named Y pasted with a string literal "Z"".
Qmake also has a few other expansion syntaxes intended to address "variables" from outside of a current .pro file:
$$(var) is a value of an environment variable of qmake process;
$(var) is a value of an environment variable of make process;
$$[var] is a value of a so-called "property", i.e. a system-wide variable managed by qmake itself (see QSettings::NativeFormat).
The proper syntax would be: $$TEST_VAR or $${TEST_VAR}
http://doc.qt.io/qt-5/qmake-language.html#variable-expansion
http://doc.qt.io/qt-5/qmake-language.html#variables
According to the user guide it is possible to assign values to variables and then perform simple arithmetic.
Imagine I have fixture designed to take an element on the page and extracting the numerical value as a Double (i do this now using the HSAC Slim BrowserTest fixture and my own code)
|script |numbers extraction |
|$testval1=|numeric value of |element1 | |
|$testval2=|numeric value of |element2 | |
Running this gives me something like:
|script |numbers extraction |
|$testval1<-[20.04]|numeric value of |element1 ->[€ 20,04] | |
|$testval2<-[5.1] |numeric value of |element2 ->[€ 5,1] | |
Now say I want to compare the sum of the two doubles with the numeric value of a third element:
|script|numbers extraction |
|check |numeric value of |element3|{=${ ${testval1} + ${testval2} =}|
No matter what combination of parentheses and dollar-signs I use in the last cell, I always get 'invalid expression'.
${= $testval1 + $testval2 =} invalid expression: $testval1 + $testval2
{${=$testval1 + $testval2 =}} {invalid expression: $testval1 + $testval2}
${=${testval1} + ${testval2} =} [invalid expression: undefined variable: testval1 + undefined variable: testval2]
${= !-$testval1-! + !-$testval2-! =} invalid expression: $testval1 + $testval2
${= !-${testval1}-! + !-${testval2}-! =} invalid expression: ${testval1} + ${testval2}
Running the last line (without parenthesis around testval1 and testval2) returns:
|check|numeric value of|element3 ->[€ 25.14]| [25.14] expected [invalid expression: $testval1->[20.04] + $testval2->[5.1]] |
Unfortunately you can can't do what you are looking for. The variables you assign the value of the elements to are actually SLIM symbols, and not variables at the wiki level. If you scroll a bit down on the user guide page you linked to in the question you will find a section called "Difference between variables and SLIM symbols":
Variables are evaluated at render time, before the test executes. This allows for values to be set based on page hierarchy and other things that are purely inputs to the tests.
Symbols only exist at execution time. They can be changed at runtime, so are distinct from variables, which cannot.
I find the three types of variables in FitNesse/SLIM are confusing to people and their different usage, syntax and possibilities cause many issues. My understanding is:
Markup variables (aka wiki variables). For instance ${myVar}, defined using !define. They get their value at page render time, so even before a test is started, so you see their value when you browse to a wiki page, and only in the page's source do you see it is a variable. These can be used in markup expressions, which is what you are trying to do in the question.
Scenario parameters. For instance #{myVar} (or #myVar), defined in the first row of a SLIM scenario table. These are the 'formal parameters' to the scenario, which get their actual value based on the invocation of the scenario (i.e. each usage of the scenario, either from a script table, other scenario or row in a decision table defines their value). They get their value at the start of a test, before its first action is performed. You see the variable when you look at the scenario table that defines it. (When you use the 'table template' table type defined by hsac-fitnesse-plugin (which is included in hsac-fitnesse-fixtures project baseline) you don't need to define the variable names in the first row of the table, they are automatically found based on their occurrence (e.g. #{myVar}) inside the table.)
SLIM symbols. For instance $myVar, they are assigned their value using $myVar=. These are 'runtime variables' that get their value during test execution, they are global to a test suite and their value might be changed during test execution. These are the only kind of variables that can get their value from a property obtained from the 'system under test', and they are the variables you are using in your question's tables. They are actually references to objects inside the SLIM process so fixtures might change the internal state of the object the variable refers to, without this change showing in the wiki representation of the variable (which is just the object's toString() result at time of last assignment).
P.S. The conversion of a string to a double does not require a custom fixture (like your numbers extraction) when you using the hsac-fitnesse-fixtures. You could just use the convert to double method of the library's string fixture.
You seem to be using browser test, this is an HSAC installation I take it? Please mention this in the question as HSAC is a FitNesse fixture.
Anyway, removing the curly brackets should do the trick. With curly brackets it is expecting a global variable, those that are implemented using !define var {foo}
When using variables that are locally defined such as with |$bar=|value of|foo| have to be called in the test using the variable without curly brackets.
|$bar=|value of|foo|
|enter|$bar|as|inputField|
Find more stuff on HSAC usage here: https://github.com/fhoeben/hsac-fitnesse-fixtures/wiki/2.-Slim-Fixtures
Sidenote:
Then there are also table templates that use #var or #{var}, where the use of #{var} is preferred because #{var} will look for the column var and #var will accept a column v or va, if you happen to implement that. Using curly brackets here ensures the full variable name is used.
I am trying to created a vector of an enumerated type in Ada, but the compiler seems to expect an equality function overload. How do I telll the compiler to just use the default equal function. Here's what I have:
package HoursWorkedVector is new Ada.Containers.Vectors(Natural,DAY_OF_WEEK);
--where Day of week is defined as an enumeration
When I try to compile, I get the message:
no visible subprogram matches the specification for "="
Do I need to create a comparison function to have a vector of an enumerated type? Thanks in advance.
The definition of Ada.Containers.Vectors starts like this:
generic
type Index_Type is range <>;
type Element_Type is private;
with function "=" (Left, Right : Element_Type)
return Boolean is <>;
package Ada.Containers.Vectors is
The meaning of <> in a generic formal function is defined by RM 12.6(10):
If a generic unit has a subprogram_default specified by a box, and the
corresponding actual parameter is omitted, then it is equivalent to an
explicit actual parameter that is a usage name identical to the
defining name of the formal.
So if, as you said in the comments, DAY_OF_WEEK is defined in another package, your instantiation is equivalent to
package HoursWorkedVector is new Ada.Containers.Vectors(Natural, Other_Package.DAY_OF_WEEK, "=");
which doesn't work because the "=" that compares DAY_OF_WEEK values is not visible.
You can include Other_Package."=" in the instantiation, as suggested in a comment. There are at least three ways to make "=" visible, so that your original instantiation would work:
use Other_Package; This will make "=" directly visible, but it will also make everything else defined in that package directly visible. This may not be what you want.
use type Other_Package.DAY_OF_WEEK; This makes all the operators of DAY_OF_WEEK directly visible, including "<", "<=", etc., as well as all the enumeration literals, and any other primitive subprograms of DAY_OF_WEEK that you may have declared in Other_Package. This is probably the favorite solution, unless for some reason it would be a problem to make the enumeration literals visible.
Use a renaming declaration to redefine "=":
function "=" (Left, Right : DAY_OF_WEEK) return Boolean
renames Other_Package."=";
This makes "=" directly visible.
The compiler automatically selects the predefined equality operator:
with
Ada.Containers.Vectors;
package Solution is
type Day_Of_Week is (Work_Day, Holiday);
package Hours_Worked_Vector is
new Ada.Containers.Vectors (Index_Type => Natural,
Element_Type => Day_Of_Week);
end Solution;
I spent some time trying to write a 'helper' macro to test a parameter for a new value, else use the existing value -- default values exist for all parameter positions.
I wanted to be able to write:
\foo{left}{nil}{}{20pt}
so that the second parameter would used its current value but the third value would be the value empty string. I wanted to use the notation:
\edef\pA{\isnil{#1}{\pA){#1}} % one for each parameter
I defined \isnil like so:
\def\nil{nil}
\def\isnil#1#2#3{%
\edef\nilTest{#1}%
\ifx\nilTest\nil#2\else#3\fi
}
but when I tried to run it, TeX complained that \nilTest is an undefined control sequence.
That is true of course, but I want \pA to hold a value, not a recipe for a value, so it must be an \edef which means that all the macro test will be expanded but while will the \edef not protect the \nilTest -- is this a place to use \noexpand -- that did not seem to work for me.
EDIT: no digits in \cs names (yeah, I knew that.)
Why doesn't your solution work? \edef\pA{\isnil{#1}{\pA){#1}} expands \isnil and gets \edef\nilTest{.... Now \edef is not expandable and falls into a sequence of \pA as the first element. An attempt to expand the next macro \nilTest fails.
Use \setpar from the following code to change your parameter.
\def\nil{nil}
\def\setpar#1#2{%
\edef\nilTest{#2}%
\ifx\nilTest\nil\else\let#1\nilTest\fi}
\def\first{old first}
\def\second{old second}
\setpar \first{nil}
\setpar \second{new}
first = ``\first'', second = ``\second''
P.S. Do not use digits in your macro.
I'm trying to understand what identifiers represent and what they don't represent.
As I understand it, an identifier is a name for a method, a constant, a variable, a class, a package/module. It covers a lot. But what can you not use it for?
Every language differs in terms of what entities/abstractions can or cannot be named and reused in that language.
In most languages, you can't use an identifier for infix arithmetic operations.
For example, plus is an identifier and you can make a function named plus. But write you can write a = b + c;, there's no way to define an operator named plus to make a = b plus c; work because the language grammar simply does not allow an identifier there.
An identifier allows you to assign a name to some data, so that you can reference it later. That is the limit of what identifiers do; you cannot "use" it for anything other than a reference to some data.
That said, there are a lot of implications that come from this, some subtle. For example, in most languages functions are, to some degree or another, considered to be data, and so a function name is an identifier. In languages where functions are values, but not "first-class" values, you can't use an identifier for a function in an place you could use an identifier for something else. In some languages, there will even be separate namespaces for functions and other data, and so what is textually the same identifier might refer to two different things, and they would be distinguished by the context in which they are used.
An example of what you usually (i.e., in most languages) cannot use an identifier for is as a reference to a language keyword. For example, this sort of thing generally can't be done:
let during = while;
during (true) { print("Hello, world."); }
You could say it's used for everything that you'll want to refer to multiple times, or maybe even once (but use it to clarify the referent's purpose).
What can/can't be named differs per language, it's often quite intuitive, IMHO.
An "Anonymous" entity is something which is not named, although referred to somehow.
#!/usr/bin/perl
$subroutine = sub { return "Anonymous subroutine returning this text"; }
In Perl-speak, this is anonymous - the subroutine is not named, but it is referred to by the reference variable $subroutine.
PS: In Perl, the subroutine would be named like this:
sub NAME_HERE {
# some code...
}
Say, in Java your cannot write something like:
Object myIf = if;
myIf (a == b) {
System.out.println("True!");
}
So, you cannot name some code statement, giving it an alias. While in REBOL it is perfectly possible:
myIf: if
myIf a = b [print "True!"]
What can and what can't be named depends on language, as you see.
as its name implifies, an identifier is used to identify something. so for everything that can be identified uniquely, you can use an identifier. But for example a literal (e.g. string literal) is not unique so you can't use an identifier for it. However you can create a variable and assign a string literal to it.
Making soup out them is rather foul.
In languages such as Lisp, an identifier exists in its own right as an symbol, whereas in languages which are not introspective identifiers don't exist in the runtime.
You write a literal identifier/symbol by putting a single quote in front of it:
[1]> 'a
A
You can create a variable and assign a symbol literal to it:
[2]> (setf a 'Hello)
HELLO
[3]> a
HELLO
[4]> (print a)
HELLO
HELLO
You can set two variables to the same symbol
[10]> (setf b a)
HELLO
[11]> b
HELLO
[12]> a
HELLO
[13]> (eq b a)
T
[14]> (eq b 'Hello)
T
Note that the values bound to b and a are the same, and the value is the literal symbol 'Hello
You can bind a function to the symbol
[15]> (defun hello () (print 'hello))
HELLO
and call it:
[16]> (hello)
HELLO
HELLO
In common lisp, the variable binding and the function binding are distinct
[19]> (setf hello 'goodbye)
GOODBYE
[20]> hello
GOODBYE
[21]> (hello)
HELLO
HELLO
but in Scheme or JavaScript the bindings are in the same namespace.
There are many other things you can do with identifiers, if they are reified as symbols. I suspect that someone more knowledgable than me in Lisp will be able to demonstrate any of the things that you 'can't do with identifiers' exist.
But even Lisp can not make identifier soup.
Sort of a left-field thought, but JSON has all those quotations in it to eliminate the danger of a JavaScript keyword messing up the parsing.