What languages provide the use of object literals? (Or in what languages could you easily emulate them?) Can you give a code example?
Starting with the obvious javascript snippet:
var someObj = {
someProperty: 123,
someFunction: function() {
alert('hello!');
}
};
Checkout C# anonymous types
var Customer = new
{
Company = "AgileApps",
Website = "http://www.agileapps.co.uk",
Name = "Big Al",
Entered = DateTime.Now
};
If you replace object by "term," then Prolog does this naturally (in fact, there's no other way to construct an object). Here's an example featuring binary trees:
% find a node in List with a nil left child and call its rightmost grandchild X
member(node(nil,node(_,X)), List).
Lisp and Scheme also have some pretty advances features in this area, particularly quoting and semiquoting:
;; construct right-leaning binary tree with x as the rightmost grandchild
`(nil . (nil . ,x))
Practically all functional programming languages have copied this in some form.
Related
I'm trying to understand how recursive set operate internally by comparing similar feature in another functional programming languages and concepts.
I can find it in wiki. In that, I need to know Y combinator, fixed point. I can get it briefly in wiki.
Then, now I start to apply this in Haskell.
Haskell
It is easy. But I want to know behind the scenes.
*Main> let x = y; y = 10; in x
10
When you write a = f b in a lazy functional language like Haskell or Nix, the meaning is stronger than just assignment. a and f b will be the same thing. This is usually called a binding.
I'll focus on a Nix example, because you're asking about recursive sets specifically.
A simple attribute set
Let's look at the initialization of an attribute set first. When the Nix interpreter is asked to evaluate this file
{ a = 1 + 1; b = true; }
it parses it and returns a data structure like this
{ a = <thunk 1>; b = <thunk 2>; }
where a thunk is a reference to the relevant syntax tree node and a reference to the "environment", which behaves like a dictionary from identifiers to their values, although implemented more efficiently.
Perhaps the reason we're evaluating this file is because you requested nix-build, which will not just ask for the value of a file, but also traverse the attribute set when it sees that it is one. So nix-build will ask for the value of a, which will be computed from its thunk. When the computation is complete, the memory that held the thunk is assigned the actual value, type = tInt, value.integer = 2.
A recursive attribute set
Nix has a special syntax that combines the functionality of attribute set construction syntax ({ }) and let-binding syntax. This is avoids some repetition when you're constructing attribute sets with some shared values.
For example
let b = 1 + 1;
in { b = b; a = b + 5; }
can be expressed as
rec { b = 1 + 1; a = b + 5; }
Evaluation works in a similar manner.
At first the evaluator returns a representation of the attribute set with all thunks, but this time the thunks reference an new environment that includes all the attributes, on top of the existing lexical scope.
Note that all these representations can be constructed while performing a minimal amount of work.
nix-build traverses attrsets in alphabetic order, so it will evaluate a first. It's a thunk that references the a + syntax node and an environment with b in it. Evaluating this requires evaluating the b syntax node (an ExprVar), which references the environment, where we find the 1 + 1 thunk, which is changed to a tInt of 2 as before.
As you can see, this process of creating thunks but only evaluating them when needed is indeed lazy and allows us to have various language constructs with their own scoping rules.
Haskell implementations usually follow a similar pattern, but may compile the code rather than interpret a syntax tree, and resolve all variable references to constant memory offsets completely. Nix tries to do this to some degree, but it must be able to fall back on strings because of the inadvisable with keyword that makes the scope dynamic.
I guess several things by myself.
In eagar evaluation language, I must declare before use it. So the order of declaration is simple.
int x = 10;
int y = x;
Just for Nix language
In wiki, there isn't any concept comparision with Haskell though let ... in is compared with Haskell.
lexical scope
all variables are lexically scoped.
mutual recursion
https://en.wikipedia.org/wiki/Let_expression#Mutually_recursive_let_expression
I'm new to functional languages and I was wondering why we can't pass a parameter by reference.
I found anserws saying that
you are not supposed to change the state of objects once they have been created
but I didn't quite get the idea.
It's not so much that you can't pass references, it's that with referential transparency there isn't a programmer-visible difference between references and values, because you aren't allowed to change what references point to. This makes it actually safer and more prevalent in pure functional programming to pass shared references around everywhere. From a semantic point of view, they may as well be values.
I think you have misunderstood the concept. Both Scheme and C/C++ are pass by value languages and most values are addresses (references).
Purely functional languages can have references and those are passed by value. What they don't have is redefining variables in the same scope (mutate bindings) and they don't have the possibility to update the object the reference points to. All operations return a fresh new object.
As an example I can give you Java's strings. Java is not purely functional but its strings are. If you change the string to uppercase you get a new string object in return and the original one has not been altered.
Most languages I know of are pass by value. Pass by name is alien to me.
Because if you pass params by reference you could change something in the parameter, which could introduce a side effect. Consider this:
function pay(person, cost) {
person.wallet -= cost;
}
function money(person) {
return person.wallet;
}
let joe = { name: "Joe", wallet: 300 };
console.log(money(joe)); // 300
pay(joe, 20);
console.log(money(joe)); // 280
The two money(joe) are taking the same input (the object joe) and giving different output (300, 280). This is in contradiction to the definition of a pure functional language (all functions must return the same output when given the same input).
If the program was made this way, there is no problem:
function pay(person, cost) {
return Object.freeze({ ...person, wallet: person.wallet - cost });
}
function money(person) {
return person.wallet;
}
let joe = Object.freeze({ name: "Joe", wallet: 300 });
console.log(money(joe)); // 300
let joe_with_less_money = pay(joe, 20);
console.log(money(joe)); // still 300
console.log(money(joe_with_less_money)); // 280
Here we have to fake pass-by-value by freezing objects (which makes them immutable) since JavaScript can pass parameters only one way (pass by sharing), but the idea is the same.
(This presupposes the implications of the term "pass-by-reference" that apply to languages like C++, where the implementation detail affects mutability, not the actual implementation detail of modern languages, where references are typically passed under the hood but immutability is assured by other means.)
I am new to haskel.What would be a good way of doing something like this in haskell?
var1 = //can be true or false
if(var1==true)
{
//return someething
}
else
{
//
}
Haskell is a functional and declarative language. That means that usually that there is not much "do something". There is more calculate something and return it.
That may look like nitpicking, but for instance in Haskell one cannot set a variable twice: once you assign it an expression (not per se a value)
, you cannot set it to a different value.
If you want to return something, you usually work with pattern matching. For instance:
f :: Bool -> String
f True = "Yes"
f False = "No"
This would be somewhat equivalent in Java/C#/... to:
public String f (boolean var1) {
if(var1) {
return "Yes";
} else {
return "No";
}
}
Note that Haskell works lazy as well: if you return a function call or anything, you do not immediately evaluate that function call: a call is only evaluated if that is necessary.
A problem might arise how to do I/O. For that, there is the concept of an I/O monad. A monad is a functional programming technique that enforces a certain order of evaluation.
But functional programming thus requires a different "mindset" than imperative programming: you do not think of a program in terms of commands that are done one after another, but more in terms of composing functions together to generate output for a given input. Like usually a mathematician or physicist does. You compose for instance a function that, given the mass and the velocity of something, calculates the kinetic energy of that object.
Haskell has if-then-else conditionals.
The closest code to yours I can write is something like this:
let var = length "hello" == 5
in if var then "ok" else "no"
Note that such conditional is more similar to C or Java's var ? "ok" : "no" expression than an if()... statement, but this is to be expected since Haskell is functional, so it has no "statements", only expressions.
Any Haskell tutorial should cover this. I'd recommend you read one, if you want to learn Haskell. Trying to convert idioms from other languages is a poor strategy.
The following scenario shows an abstraction that seems to me to be impossible to implement declaratively.
Suppose that I want to create a Symbol object which allows you to create objects with strings that can be compared, like Symbol.for() in JavaScript. A simple implementation in JS might look like this:
function MySymbol(text){//Comparable symbol object class
this.text = text;
this.equals = function(other){//Method to compare to other MySymbol
return this.text == other.text;
}
}
I could easily write this in a declarative language like Haskell:
data MySymbol = MySymbol String
makeSymbol :: String -> MySymbol
makeSymbol s = MySymbol s
compareSymbol :: MySymbol -> MySymbol -> Bool
compareSymbol (MySymbol s1) (MySymbol s2) = s1 == s2
However, maybe in the future I want to improve efficiency by using a global registry without changing the interface to the MySymbol objects. (The user of my class doesn't need to know that I've changed it to use a registry)
For example, this is easily done in Javascript:
function MySymbol(text){
if (MySymbol.registry.has(text)){//check if symbol already in registry
this.id = MySymbol.registry.get(text);//get id
} else {
this.id = MySymbol.nextId++;
MySymbol.registry.set(text, this.id);//Add new symbol with nextId
}
this.equals = function(other){//To compare, simply compare ids
return this.id == other.id;
}
}
//Setup initial empty registry
MySymbol.registry = new Map();//A map from strings to numbers
MySymbol.nextId = 0;
However, it is impossible to create a mutable global registry in Haskell. (I can create a registry, but not without changing the interface to my functions.)
Specifically, these three possible Haskell solutions all have problems:
Force the user to pass a registry argument or equivalent, making the interface implementation dependent
Use some fancy Monad stuff like Haskell's Control.Monad.Random, which would require either foreseeing the optimization from the start or changing the interface (and is basically just adding the concept of state into your program and therefore breaks referential transparency etc.)
Have a slow implementation which might not be practical in a given application
None of these solutions allow me to sufficiently abstract away implementation from my Haskell interface.
So, my question is: Is there a way to implement this optimization to a Symbol object in Haskell (or any declarative language) without causing one of the three problems listed above,
and are there any other situations where an imperative language can express an abstraction (for example an optimization like above) that a declarative language can't?
The intern package shows how. As discussed by #luqui, it uses unsafePerformIO at a few key moments, and is careful to hide the identifiers produced during interning.
Something that comes up a fair amount when dealing with heterogeneous data is the need to partially change simple objects that hold data. For instance, you might want to add, drop, or rename a property, or concatenate two objects. This is easy enough in dynamic languages, but I'm wondering if there are any clever solutions proposed by static languages?
To fix ideas, are there any languages that enable, perhaps through some sort of static mixin syntax, something like this (C#):
var hello = new { Hello = "Hello" };
var world = new { World = "World" };
var helloWorld = hello + world;
Console.WriteLine(helloWorld.ToString());
//outputs {Hello = Hello, World = World}
This certainly seems possible, since no runtime information is used. Are there static languages that have this capability?
Added:
A limited version of what I'm considering is F#'s copy-and-update record expression:
let myRecord3 = { myRecord2 with Y = 100; Z = 2 }
What you're describing is known in programming language research as record concatenation. There has been some work on static type systems for record concatenation, mostly in the context of automatic type inference a la Haskell or ML. To the best of my knowledge it has not yet made an impact on any mainstream programming languages.