What is the ":" function in Racket? - racket

I'm looking at the source code here
which has expressions like
(: track->notes (MIDITrack -> (Listof Note)))
what is the : function?
I suspect it has something to do with contracts, but can't find a reference in the documentation.

:, in this context, means "has type". It is part of the Typed Racket extension, which adds static type checking to the language.
Your example states that the function track->notes accepts a MIDITrack and returns a list of Notes.
If you want to find out more, take a look at the Typed Racket documentation.

Related

Lisp: atom and string

I am working on a simple Lisp interpreter. And now I am trying to write a parser for it. LISP - Basic Syntax. I've read that in Lisp there are only three types of block: atom, list, string. Also, I've noticed that string block can be nested into the list, like:
(format t "Some string block...~%").
Could string type of building block be considered as atom block?
First, the pages you chose as a "reference" are of a very dubious quality. The most obvious visual red flag if the "unconventional" (to put it mildly) way to format Lisp code.
Second, block in Lisp has a very specific meaning. When they use that word they, apparently, mean token.
Third, the string type in Lisp is a subtype of type atom:
(atom "foo")
==> t
Thus, the answer to the question you asked is: yes, every string is an atom.
And the answer to the question you should have asked is: refer to CLHS, not to some dubious web site.
PS. There are several FLOSS Common Lisp implementations available (e.g.,
CLISP, SBCL),
you might want to start with looking how they do things.

Is Racket (and Typed Racket) strongly or softly typed?

I realize the definitions of "strongly typed" and "softly typed" are loose and open to interpretation, but I have yet to find a clear definition in relation to untyped Racket (which from my understanding means dynamically typed) and Typed Racket on this.
Again, I'm sure its not so cut and dry, but at least I'd like to learn more about which direction leans in. The more research I've done of this the more confused I've gotten, so thank you in advance for the help!
One problem in answering questions like this is that people disagree about the meanings of nearly all of these terms. So... what follows is my opinion (though it is a fairly well-informed one, if I do say so myself).
All languages operate on some set of values, and have some runtime behavior. Trying to add a number to a function fails in nearly all languages. You can call this a "type system," but it's probably not the right term.
So what is a type system? These days, I claim that the term generally refers to a system that examines a program and statically[*] deduces properties of the program. Typically, if it's called a type system, this means attaching a "type" to each expression that constrains the set/class of values that the expression can evaluate to. Note that this definition basically makes the term "dynamically typed" meaningless.
Note the giant loophole: there's a "trivial type system", which simply assigns the "type" containing all program values to every expression. So, if you want to, you can consider literally any language to be statically typed. Or, if you prefer,
"unityped" (note the "i" in there).
Okay, down to brass tacks.
Racket is not typed. Or, if you prefer, "dynamically typed," or "unityped," or even "untyped".
Typed Racket is typed. It has a static type system that assigns to every expression a single type. Its type system is "sound", which means that evaluation
of the program will conform to the claims made by the type system: if Typed Racket
(henceforth TR) type-checks your program and assigns the type 'Natural' to an
expression, then it will definitely evaluate to a natural number (assuming no bugs
in the TR type checker or the Racket runtime system).
Typed Racket has many unusual characteristics that allow code written in TR to interoperate with code written in Racket. The most well-known of these is "occurrence typing", which allows a TR program to deal with types like (U Number String) (that is, a value that's either a number or a string) without exploding, as earlier similar type systems did.
That's kind of beside the point, though: your question was about Racket and TR, and the simple answer is that the basic Racket language does not have a static type system, and TR does.
[*] defining the term 'static' is outside the scope of this post :).
Strongly typed and weakly typed has nothing to do with static or dynamic typing. you can have a combination of them so that you have 4 variations. (strong/static, weak/static, strong/dynamic, weak/dynamic).
Scheme (and thus #lang racket) are dynamicaly and stronged typed.
> (string-append "test" 5)
string-append: contract violation
expected: string?
given: 5
argument position: 2nd
other arguments...:
All it's values have a type and the functions can demand a type. If you were to append a string to a number you get a type error. you need to explicitly cast the number to a string using number->string to satisfy the contract of all arguments being strings. With weakly typed languages, like JavaScript, it would just cast the number to a string so satisfy the function. Less code, but possibly more runtime bugs.
Since Scheme is strongly typed #lang typed/racket is definitely too.
While Scheme/#lang racket is dynamicly typed I'm not entirely sure if #lang typed/racket is completely static. The Guide calls it a gradually-typed language.
One of the definitions of "weakly typed" is that when there is a type mismatch between operands instead of giving an error the language will try its best to continue, by coercing the operands from one type to the other or giving a default result.
For example, in Perl a string containing digits will be coerced into a number if you use it in an arithmetic operation:
# This Perl program prints 6.
print 3 * "2a"
Under this definition, Racket would be categorized a dynamically typed (type errors occur at runtime) and strongly typed (it doesn't automatically convert values from one type to the other).
Since Typed Racket doesn't change the runtime semantics of Racket (except by introducing some extra contract checking) it would be just as strongly typed as regular Racket.
By the way, the usual words people use are weak and strong typing. Soft typing might refer to one specific kind of type system that was created during the 90s. It didn't turn out all that well, which is one of the reasons that people come up with the Gradual Typing system that is used in languages such as Typed Racket and Typescript.
Weakly typed language allows a legal implementation to set computer "on fire", in contrast, strongly typed language limits more buggy programs.
In spite of Racket is dynamically typed, it is strongly typed.

Want to distinguish between value and expression

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.

order of calling expressions within a defun*

Tried to use the persp-mode https://github.com/Bad-ptr/persp-mode.el/blob/master/persp-mode.el to retrieve the emacs windows session after restart. Unable to get it working.
So trying to understand the datastructure used to store the state of the emacs by reading the source code.
The following is the function which is used to store the session state.
(defun* persp-save-state-to-file (&optional (fname persp-auto-save-fname)
(phash *persp-hash*)
respect-persp-file-parameter)
(interactive (list (read-file-name "Save perspectives to file: "
persp-save-dir)))
In the above function two unusual things are observed using edebug (unusual according to my current understanding of elisp).
The optional argument expressions are evaluated.
The expression "(interactive..." is evaluated first and then the optional argument expressions are evaluated.
Any ideas how to debug the code. Also the emacs documentation says "defun*" is related to common-lisp, but no further information is available in emacs docs on how defun* is different from defun. Is there a quick tutorial oh what defun* does without having to learn common-lisp.
Emacs says:
Define NAME as a function. Like normal `defun', except ARGLIST allows
full Common Lisp conventions, and BODY is implicitly surrounded by
(cl-block NAME ...).
Common Lisp arglists provide optional, rest, keyword and aux arguments. Historically this comes from Lisp Machine Lisp and Mumble - two earlier Lisp dialects.
For details see: http://www.gnu.org/software/emacs/manual/html_node/cl/Argument-Lists.html
Have a look at this post for a simplistic snippet explaining
how optional works. The gist is that e.g. persp-auto-save-fname will be the value of fname
if none is given.
And obviously interactive has to be run first, because it provides the arguments.
So if interactive doesn't provide a value for fname it will be persp-auto-save-fname.

How do keywords work in Common Lisp?

The question is not about using keywords, but actually about keyword implementation. For example, when I create some function with keyword parameters and make a call:
(defun fun (&key key-param) (print key-param)) => FUN
(find-symbol "KEY-PARAM" 'keyword) => NIL, NIL ;;keyword is not still registered
(fun :key-param 1) => 1
(find-symbol "KEY-PARAM" 'keyword) => :KEY-PARAM, :EXTERNAL
How a keyword is used to pass an argument? Keywords are symbols whos values are themselves, so how a corresponding parameter can be bound using a keyword?
Another question about keywords — keywords are used to define packages. We can define a package named with already existing keyword:
(defpackage :KEY-PARAM) => #<The KEY-PARAMETER package, 0/16 ...
(in-package :KEY-PARAM) => #<The KEY-PARAMETER package, 0/16 ...
(defun fun (&key key-param) (print key-param)) => FUN
(fun :KEY-PARAM 1) => 1
How does system distinguish the usage of :KEY-PARAM between package name and function parameter name?
Also we can make something more complicated, if we define function KEY-PARAM and export it (actually not function, but name):
(in-package :KEY-PARAM)
(defun KEY-PARAM (&key KEY-PARAM) KEY-PARAM) => KEY-PARAM
(defpackage :KEY-PARAM (:export :KEY-PARAM))
;;exporting function KEY-PARAM, :KEY-PARAM keyword is used for it
(in-package :CL-USER) => #<The COMMON-LISP-USER package, ...
(KEY-PARAM:KEY-PARAM :KEY-PARAM 1) => 1
;;calling a function KEY-PARAM from :KEY-PARAM package with :KEY-PARAM parameter...
The question is the same, how Common Lisp does distinguish the usage of keyword :KEY-PARAM here?
If there is some manual about keywords in Common Lisp with explanation of their mechanics, I would be grateful if you posted a link here, because I could find just some short articles only about usage of the keywords.
See Common Lisp Hyperspec for full details of keyword parameters. Notice that
(defun fun (&key key-param) ...)
is actually short for:
(defun fun (&key ((:key-param key-param)) ) ...)
The full syntax of a keyword parameter is:
((keyword-name var) default-value supplied-p-var)
default-value and supplied-p-var are optional. While it's conventional to use a keyword symbol as the keyword-name, it's not required; if you just specify a var instead of (keyword-name var), it defaults keyword-name to being a symbol in the keyword package with the same name as var.
So, for example, you could do:
(defun fun2 (&key ((myoption var))) (print var))
and then call it as:
(fun 'myoption 3)
The way it works internally is when the function is being called, it steps through the argument list, collecting pairs of arguments <label, value>. For each label, it looks in the parameter list for a parameter with that keyword-name, and binds the corresponding var to value.
The reason we normally use keywords is because the : prefix stands out. And these variables have been made self-evaluating so that we don't have to quote them as well, i.e. you can write :key-param instead of ':key-param (FYI, this latter notation was necessary in earlier Lisp systems, but the CL designers decided it was ugly and redundant). And we don't normally use the ability to specify a keyword with a different name from the variable because it would be confusing. It was done this way for full generality. Also, allowing regular symbols in place of keywords is useful for facilities like CLOS, where argument lists get merged and you want to avoid conflicts -- if you're extending a generic function you can add parameters whose keywords are in your own package and there won't be collisions.
The use of keyword arguments when defining packages and exporting variables is again just a convention. DEFPACKAGE, IN-PACKAGE, EXPORT, etc. only care about the names they're given, not what package it's in. You could write
(defpackage key-param)
and it would usually work just as well. The reason many programmers don't do this is because it interns a symbol in their own package, and this can sometimes cause package conflicts if this happens to have the same name as a symbol they're trying to import from another package. Using keywords divorces these parameters from the application's package, avoiding potential problems like this.
The bottom line is: when you're using a symbol and you only care about its name, not its identity, it's often safest to use a keyword.
Finally, about distinguishing keywords when they're used in different ways. A keyword is just a symbol. If it's used in a place where the function or macro just expects an ordinary parameter, the value of that parameter will be the symbol. If you're calling a function that has &key arguments, that's the only time they're used as labels to associate arguments with parameters.
The good manual is Chapter 21 of PCL.
Answering your questions briefly:
keywords are exported symbols in keyword package, so you can refer to them not only as :a, but also as keyword:a
keywords in function argument lists (called lambda-lists) are, probably, implemented in the following way. In presence of &key modifier the lambda form is expanded into something similar to this:
(let ((key-param (getf args :key-param)))
body)
when you use a keyword to name a package it is actually used as a string-designator. This is a Lisp concept that allows to pass to a certain function dealing with strings, that are going to be used as symbols later (for different names: of packages, classes, functions, etc.) not only strings, but also keywords and symbols. So, the basic way to define/use package is actually this:
(defpackage "KEY-PARAM" ...)
But you can as well use:
(defpackage :key-param ...)
and
(defpackage #:key-param ...)
(here #: is a reader macro to create uninterned symbols; and this way is the preferred one, because you don't create unneeded keywords in the process).
The latter two forms will be converted to upper-case strings. So a keyword stays a keyword, and a package gets its named as string, converted from that keyword.
To sum up, keywords have the value of themselves, as well as any other symbols. The difference is that keywords don't require explicit qualification with keyword package or its explicit usage. And as other symbols they can serve as names for objects. Like, for example, you can name a function with a keyword and it will be "magically" accessible in every package :) See #Xach's blogpost for details.
There is no need for "the system" to distinguish different uses of keywords. They are just used as names. For example, imagine two plists:
(defparameter *language-scores* '(:basic 0 :common-lisp 5 :python 3))
(defparameter *price* '(:basic 100 :fancy 500))
A function yielding the score of a language:
(defun language-score (language &optional (language-scores *language-scores*))
(getf language-scores language))
The keywords, when used with language-score, designate different programming languages:
CL-USER> (language-score :common-lisp)
5
Now, what does the system do to distinguish the keywords in *language-scores* from those in *price*? Absolutely nothing. The keywords are just names, designating different things in different data structures. They are no more distinguished than homophones are in natural language – their use determines what they mean in a given context.
In the above example, nothing prevents us from using the function with a wrong context:
(language-score :basic *prices*)
100
The language did nothing to prevent us from doing this, and the keywords for the not-so-fancy programming language and the not-so-fancy product are just the same.
There are many possibilities to prevent this: Not allowing the optional argument for language-score in the first place, putting *prices* in another package without externing it, closing over a lexical binding instead of using the globally special *language-scores* while only exposing means to add and retrieve entries. Maybe just our understanding of the code base or convention are enough to prevent us from doing that. The point is: The system's distinguishing the keywords themselves is not necessary to achieve what we want to implement.
The specific keyword uses you ask about are not different: The implementation might store the bindings of keyword-arguments in an alist, a plist, a hash-table or whatever. In the case of package names, the keywords are just used as package designators and the package name as a string (in uppercase) might just be used instead. Whether the implementation converts strings to keywords, keywords to strings, or something entirely different internally doesn't really matter. What matters is just the name, and in which context it is used.