How is Lexical Scoping implemented? [closed] - programming-languages

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
A couple of years ago I started writing an interpreter for a little Domain Specific Language which included programmer-defined functions.
At first I implemented variable scope using a simple stack of symbol-tables. But now I want to move to proper lexical scoping (with the option of closures). Can anyone explain the data-structure and algorithm behind lexical scope?

To get correct lexical scoping and closures in an interpreter, all you need to do is follow these rules:
In your interpreter, variables are always looked up in an environment table passed in by the caller or kept as a variable, not some global env-stack. The signature of your eval operation is like eval(expression, env) => value.
When interpreted code calls a function, the environment is NOT passed to that function. The signature of your function application operation is like apply(function, arguments) => value.
When an interpreted function is called, the environment its body is evaluated in is the environment in which the function definition was made, and has nothing whatsoever to do with the caller. So if you have a local function, then it is a closure, that is, a data structure containing fields {function definition, env-at-definition-time}.
To expand on that last bit in Python-ish syntax:
x = 1
return lambda y: x + y
should be executed as if it were
x = 1
return make_closure(<AST for "lambda y: x + y">, {"x": x})
where the second dict argument may be just the current-env rather than a data structure constructed at that time. (On the other hand, retaining the entire env rather than just the closed-over variables can mean programs have surprising memory leaks because closures are holding onto things the don't need. This is worth fixing in any 'practical' language implementation but not when you are just experimenting with language semantics.)

There are many different ways to implement lexical scoping. Here are some of my favorites:
If you don't need super-fast performance, use a purely functional data structure to implement your symbol tables, and represent a nested function by a pair containing a pointer to the code and a pointer to the symbol table.
If you need native-code speeds, my favorite technique is described in Making a Fast Curry by Simon Marlow and Simon Peyton Jones.
If you need native-code speeds, but curried functions are not that important, consider closure-passing style.

Read The implementation of Lua 5.0 for instance.

There is no single right way to do this. The important thing is to clearly state the semantics that you are looking to provide, and then the data structures and algorithms will follow.

Stroustrup implemented this in the first C++ compiler simply with one symbol table per scope, and a chaining rule that followed scopes outwards until a definition is found. How this works exactly depends on your precise semantics. Make sure you nail those down first.
Knuth in The Art of Computer Programming, Vol 1, gives an algorithm for a Cobol symbol table whereby scoping is done via links.

Related

Diff between constant and variable [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
What exactly is the difference between a constant and a variable. Can constants be understood as values that can be assigned to variables in a program
You basically have the right idea. The correct idea is a bit hard to give with the small amount of information you give in your question.
"constant" is a bit vague. The name is used to refer to literals, symbolic constants, constant expressions, immutable variables ...
Anyway, the answer depends strongly on what language you're using and what context you've heard the term "constant" in.
For example, in the C programming language, most symbolic constants do not exist at runtime. They are simply names that are replaced by their actual literal values as the first step before compilation.
In other languages, constants are named variables that are saved into the built program that contain a value that can't be changed, and can be listed or so.
Wait, constants are sometimes variables?
Well, the terms "constant" and "variable" are kind of vague concepts that are sometimes used wrongly, and don't have a straight translation into machine code.
At the core, there is just memory. And memory contains data. Constants are usually parts of the memory that are just loaded from disk for you by the operating system together with your compiled code, and then your code can read them. Variables are parts of the memory for which "gaps" in memory are set aside by the system, and then your code can put values into it or read it.
That's why it's a bit hard to offer a concise definition of a variable and a constant. It depends on what level of the computer you are looking at it, through which language.
In most languages, a symbolic constant is simply a more convenient name you can use in your code to refer to a fixed number or other literal value. A name whose value you can change in one central location before you compile your code, and all other places that use the symbolic name automatically pick up the value.
Variables are boxes into which you can put any value.
So you're basically right. But there can be more to the story depending on what language you're using.
The reason for symbolic constants is mostly to make your code more readable. Instead of
leftCoordinate = 16 + 20 + 4
you can write
leftCoordinate = LEFT_MARGIN + SIDEBAR_WIDTH + LINE_WIDTH
and suddenly it is much more obvious which of these numbers you have to change to change the right part. Also, you can use them to make sure two numbers always match. Like, elsewhere in your program, you may have the code that draws the "line" mentioned above, and just do
setLineWidth(LINE_WIDTH)
drawLine(LEFT_MARGIN + SIDEBAR_WIDTH, 0, LEFT_MARGIN + SIDEBAR_WIDTH, 100)
And if you ever decide you want a thinner line, you just change the constant's value, and all your code magically updates, and you just need to recompile.

How does pure functional language(haskell) users make Design?what alternative to uml they use? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
giving that haskell doesn't have the notion objects(even it has the keyword class) How does Haskell developer design their code? how do they represent interaction/entities? does they have alternative to uml? or class equivalent?(or do they even care?)
I don't know of any formal(ized) notion of drawing or describing architecture.
Nevertheless you can structure your application
The most basic way is using the expressiveness of the type system:
wrapping simple types in newtypes - or using type synonyms to - distinguish between say an Int and an Age value, e.g. newtype Age = Age Int.
composing more complex types as products of existing e.g. data Person = Person { name :: String, age :: Age}
or by using sum types data Employee = Chef Person | Waiter Person
All these data types - which can be made much more elaborate - can be accessed/modified* via record syntax or lenses. I tend to think of the data types as my skeleton of the application I write - and use the compiler to stay true to the ideas I had when starting and never subvert the types by using unsafeXX functions.
Lack of OO/Encapsulation
I have never had - having functions attached to objects is not necessary (utterly wrong in my opinion, but that is not up for discussion here).
A basic form of encapsulation can be done via newtype and modules with their exports.
Polymorphism
A lot can already be done with typeclasses, which if you have not yet worked with them, are somewhat like interfaces, (but with less typing) - but there is a lot more you can accomplish with advanced things like type families.
Conclusion
So if I would like to draw a structure/architecture of my program, I would start with my data-types as boxes and use arrows as functions between them. And maybe use "special" boxes for container types.
*: technically one usually doesn't modify stuff, but create new values from old values as (almost) everything is immutable.

From a high level programming perspective, what is the major difference between C# and F#? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I'm aware that they both use different programming paradigms, but from a high level perspective apart from differing syntax it seems most basic tasks can be achieved in similar fashion.
I only say this because when I've previously touched functional programming languages such as Haskell, writing code for basics tasks was (at first) difficult, frustrating, and required a completely different mindset.
For example the following took some time to get to grips with using recursive syntax:
loop :: Int -> IO ()
loop n = if 0 == n then return () else loop (n-1)
Where as an F# loop is recognisable and understable almost immediately:
let list1 = [ 1; 5; 100; 450; 788 ]
for i in list1 do
printfn "%d" i
When C# programmers start learning F# they are advised to completely re-think their thought pattern (which was definitely required for Haskell), but I've now written several F# programs dealing with conditions, loops, data sets etc to perform practical tasks, and I'm wondering where the 'different-paradigm' barrier really kicks in?
Hopefully someone will be able to solve my confusion.
wThe main difference when the barrier kicks in is when people have to think in terms of functions, not in terms of objects.
Yes, it is totally possible to do object-oriented code in F#, and in this matter there is not that much of a difference between these two besides syntax. But that's not the point when using F#, even if F# allows you do to it.
The barrier kicks in when developers start solving problems in a functional way.
Here are the some of the topics that are new for C#/OO developers when learning F#/FP
Pattern matching. Sometimes people have hard times comprehending its usefulness.
Tail recursion (and the "recursive" way of solving problems)
Discriminated unions (people still try to look at them as to hierarchy of classes, IEquatable/IComparable implementations, etc instead of just thinking declaratively)
The "unit" value over "void".
Partial application (gets a bit easier as latest versions of C# allows us to deal with Funcs, but as it looks ugly not many do)
The whole concept of values over variables (including immutability)
The main difference between C# and F# is that F# gives you all this, and it makes sense to take it and use it for good.
However, yes, it is still possible writing "Csharpish" code in F# without kicking any barrier except that in this case one will hate F# for its syntax.
Your question is a bit misleading. From a very high-level perspective, pretty much all programming language are equivalent. They are all turing-complete and as such, allow you to solve the same set of problems.
From a still high-level, but more concrete perspective, C# and F# differ in so far, as F#'s functionality is a superset of C#'s. (please, do not flame me for this, I know it is not true, strictly speaking, but it gives a picture)
F# being a .net language, it inherits .net's object model and in the object-oriented subset is therefore very similar to C#, with a more lightweight syntax due to better type inference.
However, F# also supports two other paradigms:
functional programming: F# "variables", they are in fact called values, are immutable by default and as such a c# style int i = 0; i = i+1; looks very differently in F#, because you need to allow for mutability explicitly let mutable i = 0; i <- i + 1;. So if you look at the functional subset, F# is, in fact a lot closer to Haskell than it is to C#.
imperative programming: You can also write F# code in a script-oriented style, without classes, modules, etc. Just a pure script, and in this case it also looks very differently from C#.
Your example used loops similar in style to how you would write C# code and therefore it felt similar.
If you do a very small change, however, you can achieve the same thing in a way that is already quite different from C#. [ 1; 5; 100; 450; 788 ] |> List.iter (printfn "%d")
The reason why people tend to claim you need to change the way how you think about problems, is because the incentive of F#, for a C# programmer, usually is the functional subset, not the object-oriented one.
Looks like you haven't done too much Haskell?
How is, for example,
let list1 = [ 1, 5, 100, 450, 788 ]
forM_ list1 printStrLn
less recognzable?
If you like, you can even have an alias for for forM_

Why classes implicitly derive from only the Object Class? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I do not have any argument opposing why we need only a single universal class. However why not we have two universal classes, say an Object and an AntiObject Class.
In nature and in science we find the concept of duality - like Energy & Dark Energy; Male & Female; Plus & Minus; Multiply & Divide; Electrons & Protons; Integration & Derivation; and in set theory. There are so many examples of dualism that it is a philosophy in itself. In programming itself we see Anti-Patterns which helps us to perform work in contrast to how we use Design patterns.
We call it object-oriented programming. Is that a limiting factor or is there something fundamental I am missing in understanding the formation of programming languages?
Edit:
I am not sure, but the usefulness of this duality concept may lie in creating garbage collectors that create AntiObjects that combine with free or loose Objects to destruct themselves, thereby releasing memory. Or may be AntiObjects work along with Objects to create a self-modifying programming language - that allows us to create a safe self modifying code, do evolutionary computing using genetic programming, do hiding of code to prevent reverse engineering.
I've moved this question to Computer Science Site of Stack Exchange, as this is considered off-topic here. Please use that if you want to comment/answer this question.
The inheritance tree is commonly (as it is in C#) a tree, with a single root, for a number of reasons, which all seem to lead back to one big one:
If there were multiple roots, there wouldn't be a way to specify "any type of object" (aside from something like C++'s void *, which would be hideous as it tosses away any notion of "type").
Even the idea of "any type of object" loses some usefulness, as you can no longer guarantee anything about the objects you'll be accepting. How do you say "all objects have properties a, b, and c" in such a way as to let programs actually use them? You'd need an interface that all of them implement...and then, that interface becomes the root type.
GC'able languages would be useless if they couldn't collect every type of object they manage. Oops, there goes that "any type of object" again!
All-around, it's simpler to have one type be the root of the hierarchy. It lets you make contracts/guarantees/etc that apply to every object in the system, and makes fewer demands on code that wants to be able to deal with objects in a universal manner.
C++ gets away with having multiple root types because (1) C++ allows multiple inheritance, so objects can bridge the gaps between inheritance trees; (2) it has templates (which are far, far more able than generics to take any type of object); (3) it can discard and sidestep any notion of "type" altogether via means like void *; and (4) it doesn't offer to manage and collect your objects for you.
C# didn't want all the complexity of multiple inheritance and templates, and it wanted garbage collection.
In Nature, if in a family there are two children who are totally different and opposite from each other, still they have common parents.
All those examples which you have given come under common category. For e.g. Male and Female comes under Homosapiens Category. Plus and Minus come under Operator category.
In OOPS also there are two types. Reference type and value type but still they both come under object.
What you are suggesting is also good. But let us for a second, in a universe, accept what you are suggesting. Still there will be a Super_Class containing your Object and AntiObject class. So it has to stop somewhere and in OOPS object is that class where it stops.

Haskell library like SymPy? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I need to manipulate expressions like 1 + sqrt(3) and do basic arithmetic like addition, subtraction, and division. I'd like the result to be in some sort of canonical form so that it can be used as a key in a map. Turning 1 + sqrt(3) into a float is not feasible due to roundoff problems.
I used SymPy for this task in Python. Is there an equivalent native library for Haskell?
Please check out the numbers package. If all you need is to store exact numbers like "1 + √3", you may want to use Data.Number.CReal instead of symbolic arithmetics. It stores the expressions and can be computed to arbitrary number of digits when needed.
Prelude Data.Number.CReal> let cx = 1 + sqrt (3 :: CReal)
Prelude Data.Number.CReal> showCReal 400 cx
"2.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067030299699450949989524788116555120943736485280932319023055820679748201010846749232650153123432669033228866506722546689218379712270471316603678615880190499865373798593894676503475065760507566183481296061009476021871903250831458295239598329977898245082887144638329173472241639845878553977"
There is also a Data.Number.Symbolic module in the package but the description says "It's mainly useful for debugging".
It seems you are looking for Computer Algebra System (CAS) in Haskell. Inspite of so many references to algebraic objects in the names of Haskell packages/modules, I've never heard of a general purpose and well-maintained CA system in Haskell (like SymPy or Sage in Python).
However in the list of Computer Algebra Systems on Wikipedia I've found a reference to
DoCon. The Algebraic Domain Constructor
It uses a non-standard license, but I dare say it is still Open Source (though with rename and attribution requirements). As of July 2010 docon-2.11 still builds with GHC 6.12.1 and runs demos/tests (I only had to insert a LANGUAGE FlexibleContexts pragma in one file of the demo).
DoCon is well documented (362 pages of the Manual). Its Manual is packed inside of the zip with sources, so I put it online separately for convenience:
DoCon 2.11 Manual.ps
Please look through to check if it suits your needs.
Check out the cyclotomic package, which implements exact arithmetic on the cyclotomic numbers. These include all algebraic numbers (hence in particular 1+sqrt(3)) and the key operations (like equality) are decidable.
They do not provide an Ord instance (for the same reason the complex numbers do not), but one can implement a non-semantic instance if all one needs is to use them as keys in a lookup table. You may want to contact the author about how to do this correctly, as there may be some invariants that are not obvious (e.g. one may need to be careful about zeros in the coeffs map).

Resources