Which syntax to choose for the semantics steps.fals as target and source module? - lightning-workbench

For the semantics section when initializing the steps.fals which part should be selected as source module and target module - the abstract or the concrete syntax?

Normally, the semantics is defined in Lightning as an endogenous transformation from/to the Semantics Domain Model

Related

Is the "define" primitive of Scheme an imperative languages feature? Why or why not?

(define hypot
(lambda (a b)
(sqrt (+ (* a a) (* b b)))))
This is a Scheme programming language.
"define" creates a variable and global binding
lambda creates a procedure
I would like to know if "define" would be considered as an imperative language feature! As long as I know imperative feature is static scoping. I think it is an imperative feature since "define" create a global binding and static scoped looks at global binding for any variable definition where as in dynamic it looks at the current most active binding.
Please help me find the correct answer!! And I would like to know why or why not?
In a Scheme program (define var expr) statement is both a declaration and an initialization. Declarations introduce a new name into the scope. Declarations and initialization are present in both imperative and declarative languages.
However if the same variable is defined twice, then define behave as an assignment - which belongs to the imperative paradigm.
You've put your finger on a subtle and contentious issue. There have long been two informal camps on how define should work, which I would label (very imperfectly, and very controversially!) as the static vs. dynamic camps.
The static camp sees define as a non-side-effecting top-level declaration—it's a syntax that simply defines a name in a top-level scope, just like let is a syntax that defines a name in a local scope. A bit more precisely, this camp tends to see the top-level environment as equivalent to a big letrec with all the defines as the bindings, and all "loose" top-level expressions as the body. This is, incidentally, similar to the way that simple compilers work—read the whole program from one or more files, figure out all of the top-level bindings and generate code with knowledge of the whole program's source text.
The dynamic camp, on the other hand, tends to conceive of the top-level environment as a mutable data structure to which bindings can be added at runtime, and define is then an operation that modifies the top-level environment. This is, incidentally, similar to how simple interactive interpreters work—read definitions interactively from input, one at a time, and incorporate them into the environment as the user provides them.
To give one example, the SLIB library is one that I recall has been criticized for being much too firmly in the "dynamic" camp. If you read Section 1.1 on "features", you see this right from the beginning:
SLIB maintains a list of features supported by a Scheme session. The set of features provided by a session may change during that session.
The documentation for the require form that you use in SLIB to "load" modules continues with this:
Procedure: require feature
If (provided? feature) is true, then require just returns.
Otherwise, if feature is found in the catalog, then the corresponding files will be loaded and (provided? feature) will henceforth return #t. That feature is thereafter provided.
Otherwise (feature not found in the catalog), an error is signaled.
If you read this carefully, you will be struck that it's framing the whole thing as modules being "loaded" at runtime—and not as compile-time linking, which is foreign to the design.
So a "session" is a set of bindings whose keys—not just their values—changes during the runtime of the program. Programs are able to mutate the session with provide and require. They are able to directly observe the mutation with provided?. And it is implied that they can indirectly observe the set of identifiers bound in top-level environment change as a result of require—a call to require causes procedure invocations that would result in a runtime error before its invocation to no longer be so afterwards.
So we can't help but conclude that going by the philosophy of the people who designed this library, define is imperative. But not every Scheme user or implementer shares this philosophy.
First off Scheme is lexically scoped. Define usually is not limited to top level bindings like it is in Racket. It can create bindings within other procedure bodies.
In some implementations define can manipulate state but only for top level definitions. Otherwise it acts like let and binds a variable to the local scope. To actually take advantage of the top-level rebinding programatically is difficult.
So define doesn't introduce an imperative style into scheme code. Compare define to set! and its relatives, which by modify the variable in whatever environment it is bound, thereby allowing imperative style in scheme code.

Rationale behind Ada encapsulation of dynamically dispatching operations (primitives)

In Ada, Primitive operations of a type T can only be defined in the package where T is defined. For example, if a Vehicules package defines Car and Bike tagged record, both inheriting a common Vehicle abstract tagged type, then all operations than can dispatch on the class-wide Vehicle'Class type must be defined in this Vehicles package.
Let's say that you do not want to add primitive operations: you do not have the permission to edit the source file, or you do not want to clutter the package with unrelated features.
Then, you cannot define operations in other packages that implicitely dispatches on type Vehicle'Class.
For example, you may want to serialize vehicles (define a Vehicles_XML package with a To_Xml dispatching function) or display them as UI elements (define a Vehicles_GTK package with Get_Label, Get_Icon, ... dispatching functions), etc.
The only way to perform dynamic dispatch is to write the code explicitely; for example, inside Vechicle_XML:
if V in Car'Class then
return Car_XML (Car (V));
else
if V in Bike'Class then
return Bike_XML (Bike (V));
else
raise Constraint_Error
with "Vehicle_XML is only defined for Car and Bike."
end if;
(And a Visitor pattern defined in Vehicles and used elsewhere would work, of course, but that still requires the same kind of explicit dispatching code. edit in fact, no, but there is still some boilerplate code to write)
My question is then:
is there a reason why operations dynamically dispatching on T are restricted to be defined in the defining package of T?
Is this intentional? Is there some historical reasons behind this?
Thanks
EDIT:
Thanks for the current answers: basically, it seems that it is a matter of language implementation (freezing rules/virtual tables).
I agree that compilers are developped incrementally over time and that not all features fit nicely in an existing tool.
As such, isolating dispatching operators in a unique package seems to be a decision mostly guided by existing implementations than by language design. Other languages outside of the C++/Java family provide dynamic dispatch without such requirement (e.g. OCaml, Lisp (CLOS); if that matters, those are also compiled languages, or more precisely, language for which compilers exist).
When I asked this question, I wanted to know if there were more fundamental reasons, at language specification level, behind this part of Ada specifications (otherwise, does it really mean that the specification assumes/enforces a particular implementation of dynamic disapatch?)
Ideally, I am looking for an authoritative source, like a rationale or guideline section in Reference Manuals, or any kind of archived discussion about this specific part of the language.
I can think of several reasons:
(1) Your example has Car and Bike defined in the same package, both derived from Vehicles. However, that's not the "normal" use case, in my experience; it's more common to define each derived type in its own package. (Which I think is close to how "classes" are used in other compiled languages.) And note also that it's not uncommon to define new derived types afterwards. That's one of the whole points of object-oriented programming, to facilitate reuse; and it's a good thing if, when designing a new feature, you can find some existing type that you can derive from, and reuse its features.
So suppose you have your Vehicles package that defines Vehicle, Car, and Bike. Now in some other package V2, you want to define a new dispatching operation on a Vehicle. For this to work, you have to provide the overriding operations for Car and Bike, with their bodies; and assuming you are not allowed to modify Vehicles, then the language designers have to decide where the bodies of the new operation have to be. Presumably, you'd have to write them in V2. (One consequence is that the body that you write in V2 would not have access to the private part of Vehicles, and therefore it couldn't access implementation details of Car or Bike; so you could only write the body of that operation if terms of already-defined operations.) So then the question is: does V2 need to provide operations for all types that are derived from Vehicle? What about types derived from Vehicle that don't become part of the final program (maybe they're derived to be used in someone else's project)? What about types derived from Vehicle that haven't yet been defined (see preceding paragraph)? In theory, I suppose this could be made to work by checking everything at link time. However, that would be a major paradigm change for the language. It's not something that could be easily. (It's pretty common, by the way, for programmers to think "it would be nice to add feature X to a language, and it shouldn't be too hard because X is simple to talk about", without realizing just what a vast impact such a "simple" feature would have.)
(2) A practical reason has to do with how dispatching is implemented. Typically, it's done with a vector of procedure/function pointers. (I don't know for sure what the exact implementation is in all cases, but I think this is basically the case for every Ada compiler as well as for C++ and Java compilers, and probably C#.) What this means is that when you define a tagged type (or a class, in other languages), the compiler will set up a vector of pointers, and based on how many operations are defined for the type, say N, it will reserve slots 1..N in the vector for the addresses of the subprograms. If a type is derived from that type and defines overriding subprograms, the derived type gets its own vector, where slots 1..N will be pointers to the actual overriding subprograms. Then, when calling a dispatching subprogram, a program can look up the address in some known slot index assigned to that subprogram, and it will jump to the correct address depending on the object's actual type. If a derived type defines new primitive subprograms, new slots are assigned N+1..N2, and types derived from that could define new subprograms that get slots N2+1..N3, and so on.
Adding new dispatching subprograms to Vehicle would interfere with this. Since new types have been derived from Vehicle, you can't insert a new area into the vector after N, because code has already been generated that assumes the slots starting at N+1 have been assigned to new operations derived for derived types. And since we may not know all the types that have been derived from Vehicle and we don't know what other types will be derived from Vehicle in the future and how many new operations will be defined for them, it's hard to pick some other location in the vector that could be used for the new operations. Again, this could be done if all of the slot assignment were deferred until link time, but that would be a major paradigm change, again.
To be honest, I can think of other ways to make this work, by adding new operations not in the "main" dispatch vector but in an auxiliary one; dispatching would probably require a search for the correct vector (perhaps using an ID assigned to the package that defines the new operations). Also, adding interface types to Ada 2005 has already complicated the simple vector implementation somewhat. But I do think this (i.e. it doesn't fit into the model) is one reason why the ability to add new dispatching operations like you suggest isn't present in Ada (or in any other compiled language that I know of).
Without having checked the rationale for Ada 95 (where tagged types were introduced), I am pretty sure the freezing rules for tagged types are derived from the simple requirement that all objects in T'Class should have all the dispatching operations of type T.
To fulfill that requirement, you have to freeze type and say that no more dispatching operations can be added to type T once you:
Derive a type from T, or
Are at the end of the package specification where T was declared.
If you didn't do that, you could have a type derived from type T (i.e. in T'Class), which hadn't inherited all the dispatching operations of type T. If you passed an object of that type as a T'Class parameter to a subprogram, which knew of one more dispatching operation on type T, a call to that operation would have to fail. - We wouldn't want that to happen.
Answering your extended question:
Ada comes with both a Reference Manual (the ISO standard), a Rationale and an Annotated Reference Manual. And a large part of the discussions behind these documents are public as well.
For Ada 2012 see http://www.adaic.org/ada-resources/standards/ada12/
Tagged types (dynamic dispatching) was introduced in Ada 95. The documents related to that version of the standard can be found at http://www.adaic.org/ada-resources/standards/ada-95-documents/

MPIR Prefix in MPICH/MVAPICH

The following link represent function name prefix conventions in MPICH/MVAPICH (e.g., MPID and MPIU prefixes)
Function Name Prefix Convention in MPICH/MVAPICH
I am just wondering what MPIR prefix represents (not explained in the link above)? At which layer it is implemented and which layers have access to it?
Thanks in advnace
MPIR_ is usually used for symbols which are defined in the top-level layer which is below the actual MPI_ interface but above the Abstract Device Interface (ADI), whose symbols usually have an MPID_ prefix. Most MPIU_ symbols are also defined at this layer, but they are usually for completely separate utility routines which do not implement any "MPI business logic". As always with these naming conventions, the convention has not been followed 100% strictly in all cases.
Source: my brain; I've been developing MPICH for >5 years.
Using non-MPI_ names for routines defined inside the library is important, since it means that we won't accidentally stomp on the MPI namespace and potentially conflict with future standardization or confuse users about what is actually standard functionality: http://www.mpi-forum.org/docs/mpi22-report/node31.htm#Node31
We use the ISO C declaration format. All MPI names have an MPI_ prefix, defined constants are in all capital letters, and defined types and functions have one capital letter after the prefix. Programs must not declare variables or functions with names beginning with the prefix MPI_. To support the profiling interface, programs should not declare functions with names beginning with the prefix PMPI_.

Is Gosu C# for the JVM?

From what I gather, Gosu is simply C# for the JVM (which is a good thing). Is it true? What are some difference between Gosu and C# (Except the class library and the fact it runs on JVM) ?
We didn't build Gosu to be one language or the other for the JVM. Rather we built Gosu to be a useful language for the JVM. In addition, we recognized that Gosu needed to be familiar to the multitudes of existing programmers who are most comfortable with the imperative, object-oriented model. To achieve that we borrowed heavily from several languages e.g., Java, C#, EcmaScript, Ruby, and some others. The result, we think, is a language that is uniquely positioned on the JVM.
What is entirely unique about Gosu, however, is it's open type system.
Gosu's type system consists of a configurable number of type loaders. A type loader's primary responsibility is to resolve a type name in its domain and return an implementation of Gosu's IType interface. This is what is most unique about Gosu -- its type system is open to other domains to participate with first-class representation. I frequently use the term, DST (Domain Specific Type), to get across the idea. For instance, Gosu does not discriminate between a Gosu Class a Java Class or XML Type or what have you; they're all just types to Gosu's compiler. Check out the DynamicType example in the download to get a glimpse of the power and breadth the open type system provides. Essentially, the example demonstrates that C#'s "dynamic types where required" can simply be a new type loader domain in Gosu. Or check out the Ronin framework to see how easily the web and database domains can map seamlessly into Gosu.
It is important to understand that not all type loader domains in Gosu are required to produce bytecode. Those that do implement an interface for getting at the corresponding Java class. Those that don't provide call handlers and property accessors for reflective MethodInfo and PropertyInfo evaluation, respectively. Note all types provide TypeInfo, see IType.getTypeInfo(). For instance, the parser works against the TypeInfo, MethodInfo, etc. abstractions as the means for a level playing field between disparate types. At runtime, however, unless a type provides a Java bytecode class the MethodInfos and PropertyInfos also are responsible for handling calls.
No. If you look at the "notable differences" page (differences between Java and Gosu) you'll see a lot of things which are like C#, but also things which aren't in C# such as case-insensitivity and making semi-colons optional. There are also things which certainly aren't mentioned but which are part of C#:
Custom value types
Operator overloading
LINQ
Dynamic typing where required
I think it would be a mistake to regard Gosu as "C# for the JVM" rather than "a JVM language which mixes bits of Java, bits of C# and some bits from other languages too".

Describe the Damas-Milner type inference in a way that a CS101 student can understand

Hindley-Milner is a type system that is the basis of the type systems of many well known functional programming languages. Damas-Milner is an algorithm that infers (deduces?) types in a Hindley-Milner type system.
Wikipedia gives a description of the algorithm which, as far as I can tell, amounts to a single word: "unification." Is that all there is to it? If so, that means that the interesting part is the type system itself not the type inference system.
If Damas-Milner is more than unification, I would like a description of Damas-Milner that includes a simple example and, ideally, some code.
Also, this algorithm is often said to do type inference. Is it really an inference system? I thought it was only deducing the types.
Related questions:
What is Hindley Miller?
Type inference to unification problem
Damas Milner is just a structured use of unification.
When it recurses into a lambda expression it makes up a new variable name. When you, in a sub-term, find that variable used in a way that would require a given type, it records the unification of that variable and that type. If it ever tries to unify two types that don't make sense, like saying that an individual variable is both an Int and a function from a -> b, then it yells at you for doing something bad.
Also, this algorithm is often said to do type inference. Is it really an inference system? I thought it was only deducing the types.
Deducing the types is type inference. Checking to see that type annotations are valid for a given term is type checking. They are different problems.
If so, that means that the interesting part is the type system itself not the type inference system.
It is commonly said that Hindley-Milner style type systems are balanced on a cusp. If you add much more functionality it becomes impossible to infer the types. So type system extensions that you can layer on top of a Hindley-Milner style type system without destroying its inference properties are really the interesting parts of modern functional languages. In some cases, we mix type inference and type checking, for instance in Haskell a lot of modern extensions can't be inferred, but can be checked, so they require type annotations for advanced features, like polymorphic recursion.
Wikipedia gives a description of the algorithm which, as far as I can tell, amounts to a single word: "unification." Is that all there is to it? If so, that means that the interesting part is the type system itself not the type inference system.
IIRC, the interesting part of the Damas-Milner type inference Algorithm W is that it infers the most general types possible.

Resources