I had a task where I wanted to find the closest string to a target (so, edit distance) without generating them all at the same time. I figured I'd use the high water mark technique (low, I guess) while initializing the closest edit distance to Inf so that any edit distance is closer:
use Text::Levenshtein;
my #strings = < Amelia Fred Barney Gilligan >;
for #strings {
put "$_ is closest so far: { longest( 'Camelia', $_ ) }";
}
sub longest ( Str:D $target, Str:D $string ) {
state Int $closest-so-far = Inf;
state Str:D $closest-string = '';
if distance( $target, $string ) < $closest-so-far {
$closest-so-far = $string.chars;
$closest-string = $string;
return True;
}
return False;
}
However, Inf is a Num so I can't do that:
Type check failed in assignment to $closest-so-far; expected Int but got Num (Inf)
I could make the constraint a Num and coerce to that:
state Num $closest-so-far = Inf;
...
$closest-so-far = $string.chars.Num;
However, this seems quite unnatural. And, since Num and Int aren't related, I can't have a constraint like Int(Num). I only really care about this for the first value. It's easy to set that to something sufficiently high (such as the length of the longest string), but I wanted something more pure.
Is there something I'm missing? I would have thought that any numbery thing could have a special value that was greater (or less than) all the other values. Polymorphism and all that.
{new intro that's hopefully better than the unhelpful/misleading original one}
#CarlMäsak, in a comment he wrote below this answer after my first version of it:
Last time I talked to Larry about this {in 2014}, his rationale seemed to be that ... Inf should work for all of Int, Num and Str
(The first version of my answer began with a "recollection" that I've concluded was at least unhelpful and plausibly an entirely false memory.)
In my research in response to Carl's comment, I did find one related gem in #perl6-dev in 2016 when Larry wrote:
then our policy could be, if you want an Int that supports ±Inf and NaN, use Rat instead
in other words, don't make Rat consistent with Int, make it consistent with Num
Larry wrote this post 6.c. I don't recall seeing anything like it discussed for 6.d.
{and now back to the rest of my first answer}
Num in P6 implements the IEEE 754 floating point number type. Per the IEEE spec this type must support several concrete values that are reserved to stand in for abstract concepts, including the concept of positive infinity. P6 binds the corresponding concrete value to the term Inf.
Given that this concrete value denoting infinity already existed, it became a language wide general purpose concrete value denoting infinity for cases that don't involve floating point numbers such as conveying infinity in string and list functions.
The solution to your problem that I propose below is to use a where clause via a subset.
A where clause allows one to specify run-time assignment/binding "typechecks". I quote "typecheck" because it's the most powerful form of check possible -- it's computationally universal and literally checks the actual run-time value (rather than a statically typed view of what that value can be). This means they're slower and run-time, not compile-time, but it also makes them way more powerful (not to mention way easier to express) than even dependent types which are a relatively cutting edge feature that those who are into advanced statically type-checked languages tend to claim as only available in their own world1 and which are intended to "prevent bugs by allowing extremely expressive types" (but good luck with figuring out how to express them... ;)).
A subset declaration can include a where clause. This allows you to name the check and use it as a named type constraint.
So, you can use these two features to get what you want:
subset Int-or-Inf where Int:D | Inf;
Now just use that subset as a type:
my Int-or-Inf $foo; # ($foo contains `Int-or-Inf` type object)
$foo = 99999999999; # works
$foo = Inf; # works
$foo = Int-or-Inf; # works
$foo = Int; # typecheck failure
$foo = 'a'; # typecheck failure
1. See Does Perl 6 support dependent types? and it seems the rough consensus is no.
I am trying to migrate my scripts from mathematica to sage. I am stuck in something that it seems elementary.
I need to work with arbitrarily large polynomials say of the form
a00 + a10*x + a01*y + a20 *x^2 + a11*x*y + ...
I consider them polynomials only on x and y and I need given such a polynomial P to get the list of its monomials.
For example if P = a20*x^2 + a12*x*y^2
I want a list of the form [a20*x^2,a12*x*y^2].
I figured out that a polynomial in sage has a class function called coefficients that returns the coefficients and a class function called monomials that returns the monomials without the coefficients. Multiplying these two list together, gives the result I want.
The problem is that for this to work I need to explicitly declare all the a's as variables with is something that is not always possible.
Is there any way to tell sage that anything of the form a[number][number] is a variable? Or is there any way to define a whole family of variables in sage?
In a perfect world I would like to make sage behave like mathematica, in the sense that anything which is not defines is considered a variable, but I guess this is too optimistic.
My answer is not fully addressing your question but one trick I found to define variables was to use the PolynomialRing(). For example:
sage: R = PolynomialRing(RR, 'c', 20)
sage: c = R.gens()
sage: pol=sum(c[i]*x^i for i in range(10));pol
c9*x^9 + c8*x^8 + c7*x^7 + c6*x^6 + c5*x^5 + c4*x^4 + c3*x^3 + c2*x^2 + c1*x + c0
and later on you can define them as variables to solve(), for example:
sage: variables=[SR(c[i]) for i in srange(0,len(eq_list))];
sage: solution = solve(eqs,variables);
You'll almost certainly need some very minor string processing; the answers
this way of getting lists of symbolic variables
this other way of getting them that is similar
this sage-support post
are better than anything I can say. Naturally, this is possible to implement, but ...
In a perfect world I would like to make sage behave like mathematica, in the sense that anything which is not defines is considered a variable, but I guess this is too optimistic.
True; indeed, that goes against Python's (and hence Sage's) philosophy of "explicit is better than implicit"; there were arguments for a long time over whether even x should be predefined as a symbolic variable (it is!).
(And truthfully, given how often I make typos, I'd really rather not have any arbitrary thing be considered a symbolic variable.)
I've created an interprter for a simple language. It is AST based (to be more exact, an irregular heterogeneous AST) with visitors executing and evaluating nodes. However I've noticed that it is extremely slow compared to "real" interpreters. For testing I've ran this code:
i = 3
j = 3
has = false
while i < 10000
j = 3
has = false
while j <= i / 2
if i % j == 0 then
has = true
end
j = j+2
end
if has == false then
puts i
end
i = i+2
end
In both ruby and my interpreter (just finding primes primitively). Ruby finished under 0.63 second, and my interpreter was over 15 seconds.
I develop the interpreter in C++ and in Visual Studio, so I've used the profiler to see what takes the most time: the evaluation methods.
50% of the execution time was to call the abstract evaluation method, which then casts the passed expression and calls the proper eval method. Something like this:
Value * eval (Exp * exp)
{
switch (exp->type)
{
case EXP_ADDITION:
eval ((AdditionExp*) exp);
break;
...
}
}
I could put the eval methods into the Exp nodes themselves, but I want to keep the nodes clean (Terence Parr saied something about reusability in his book).
Also at evaluation I always reconstruct the Value object, which stores the result of the evaluated expression. Actually Value is abstract, and it has derived value classes for different types (That's why I work with pointers, to avoid object slicing at returning). I think this could be another reason of slowness.
How could I make my interpreter as optimized as possible? Should I create bytecodes out of the AST and then interpret bytecodes instead? (As far as I know, they could be much faster)
Here is the source if it helps understanding my problem: src
Note: I haven't done any error handling yet, so an illegal statement or an error will simply freeze the program. (Also sorry for the stupid "error messages" :))
The syntax is pretty simple, the currently executed file is in OTZ1core/testfiles/test.txt (which is the prime finder).
I appreciate any help I can get, I'm really beginner at compilers and interpreters.
One possibility for a speed-up would be to use a function table instead of the switch with dynamic retyping. Your call to the typed-eval is going through at least one, and possibly several, levels of indirection. If you distinguish the typed functions instead by name and give them identical signatures, then pointers to the various functions can be packed into an array and indexed by the type member.
value (*evaltab[])(Exp *) = { // the order of functions must match
Exp_Add, // the order type values
//...
};
Then the whole switch becomes:
evaltab[exp->type](exp);
1 indirection, 1 function call. Fast.
Most of the mainstream languages, including object-oriented programming (OOP) languages such as C#, Visual Basic, C++, and Java were designed to primarily support imperative (procedural) programming, whereas Haskell/gofer like languages are purely functional. Can anybody elaborate on what is the difference between these two ways of programming?
I know it depends on user requirements to choose the way of programming but why is it recommended to learn functional programming languages?
Here is the difference:
Imperative:
Start
Turn on your shoes size 9 1/2.
Make room in your pocket to keep an array[7] of keys.
Put the keys in the room for the keys in the pocket.
Enter garage.
Open garage.
Enter Car.
... and so on and on ...
Put the milk in the refrigerator.
Stop.
Declarative, whereof functional is a subcategory:
Milk is a healthy drink, unless you have problems digesting lactose.
Usually, one stores milk in a refrigerator.
A refrigerator is a box that keeps the things in it cool.
A store is a place where items are sold.
By "selling" we mean the exchange of things for money.
Also, the exchange of money for things is called "buying".
... and so on and on ...
Make sure we have milk in the refrigerator (when we need it - for lazy functional languages).
Summary: In imperative languages you tell the computer how to change bits, bytes and words in it's memory and in what order. In functional ones, we tell the computer what things, actions etc. are. For example, we say that the factorial of 0 is 1, and the factorial of every other natural number is the product of that number and the factorial of its predecessor. We don't say: To compute the factorial of n, reserve a memory region and store 1 there, then multiply the number in that memory region with the numbers 2 to n and store the result at the same place, and at the end, the memory region will contain the factorial.
Definition:
An imperative language uses a sequence of statements to determine how to reach a certain goal. These statements are said to change the state of the program as each one is executed in turn.
Examples:
Java is an imperative language. For example, a program can be created to add a series of numbers:
int total = 0;
int number1 = 5;
int number2 = 10;
int number3 = 15;
total = number1 + number2 + number3;
Each statement changes the state of the program, from assigning values to each variable to the final addition of those values. Using a sequence of five statements the program is explicitly told how to add the numbers 5, 10 and 15 together.
Functional languages:
The functional programming paradigm was explicitly created to support a pure functional approach to problem solving. Functional programming is a form of declarative programming.
Advantages of Pure Functions:
The primary reason to implement functional transformations as pure functions is that pure functions are composable: that is, self-contained and stateless. These characteristics bring a number of benefits, including the following:
Increased readability and maintainability. This is because each function is designed to accomplish a specific task given its arguments. The function does not rely on any external state.
Easier reiterative development. Because the code is easier to refactor, changes to design are often easier to implement. For example, suppose you write a complicated transformation, and then realize that some code is repeated several times in the transformation. If you refactor through a pure method, you can call your pure method at will without worrying about side effects.
Easier testing and debugging. Because pure functions can more easily be tested in isolation, you can write test code that calls the pure function with typical values, valid edge cases, and invalid edge cases.
For OOP People or
Imperative languages:
Object-oriented languages are good when you have a fixed set of operations on things and as your code evolves, you primarily add new things. This can be accomplished by adding new classes which implement existing methods and the existing classes are left alone.
Functional languages are good when you have a fixed set of things and as your code evolves, you primarily add new operations on existing things. This can be accomplished by adding new functions which compute with existing data types and the existing functions are left alone.
Cons:
It depends on the user requirements to choose the way of programming, so there is harm only when users don’t choose the proper way.
When evolution goes the wrong way, you have problems:
Adding a new operation to an object-oriented program may require editing many class definitions to add a new method
Adding a new kind of thing to a functional program may require editing many function definitions to add a new case.
Most modern languages are in varying degree both imperative and functional but to better understand functional programming, it will be best to take an example of pure functional language like Haskell in contrast of imperative code in not so functional language like java/C#. I believe it is always easy to explain by example, so below is one.
Functional programming: calculate factorial of n i.e n! i.e n x (n-1) x (n-2) x ...x 2 X 1
-- | Haskell comment goes like
-- | below 2 lines is code to calculate factorial and 3rd is it's execution
factorial 0 = 1
factorial n = n * factorial (n - 1)
factorial 3
-- | for brevity let's call factorial as f; And x => y shows order execution left to right
-- | above executes as := f(3) as 3 x f(2) => f(2) as 2 x f(1) => f(1) as 1 x f(0) => f(0) as 1
-- | 3 x (2 x (1 x (1)) = 6
Notice that Haskel allows function overloading to the level of argument value. Now below is example of imperative code in increasing degree of imperativeness:
//somewhat functional way
function factorial(n) {
if(n < 1) {
return 1;
}
return n * factorial(n-1);
}
factorial(3);
//somewhat more imperative way
function imperativeFactor(n) {
int f = 1;
for(int i = 1; i <= n; i++) {
f = f * i;
}
return f;
}
This read can be a good reference to understand that how imperative code focus more on how part, state of machine (i in for loop), order of execution, flow control.
The later example can be seen as java/C# lang code roughly and first part as limitation of the language itself in contrast of Haskell to overload the function by value (zero) and hence can be said it is not purist functional language, on the other hand you can say it support functional prog. to some extent.
Disclosure: none of the above code is tested/executed but hopefully should be good enough to convey the concept; also I would appreciate comments for any such correction :)
Functional Programming is a form of declarative programming, which describe the logic of computation and the order of execution is completely de-emphasized.
Problem: I want to change this creature from a horse to a giraffe.
Lengthen neck
Lengthen legs
Apply spots
Give the creature a black tongue
Remove horse tail
Each item can be run in any order to produce the same result.
Imperative Programming is procedural. State and order is important.
Problem: I want to park my car.
Note the initial state of the garage door
Stop car in driveway
If the garage door is closed, open garage door, remember new state; otherwise continue
Pull car into garage
Close garage door
Each step must be done in order to arrive at desired result. Pulling into the garage while the garage door is closed would result in a broken garage door.
//The IMPERATIVE way
int a = ...
int b = ...
int c = 0; //1. there is mutable data
c = a+b; //2. statements (our +, our =) are used to update existing data (variable c)
An imperative program = sequence of statements that change existing data.
Focus on WHAT = our mutating data (modifiable values aka variables).
To chain imperative statements = use procedures (and/or oop).
//The FUNCTIONAL way
const int a = ... //data is always immutable
const int b = ... //data is always immutable
//1. declare pure functions; we use statements to create "new" data (the result of our +), but nothing is ever "changed"
int add(x, y)
{
return x+y;
}
//2. usage = call functions to get new data
const int c = add(a,b); //c can only be assigned (=) once (const)
A functional program = a list of functions "explaining" how new data can be obtained.
Focus on HOW = our function add.
To chain functional "statements" = use function composition.
These fundamental distinctions have deep implications.
Serious software has a lot of data and a lot of code.
So same data (variable) is used in multiple parts of the code.
A. In an imperative program, the mutability of this (shared) data causes issues
code is hard to understand/maintain (since data can be modified in different locations/ways/moments)
parallelizing code is hard (only one thread can mutate a memory location at the time) which means mutating accesses to same variable have to be serialized = developer must write additional code to enforce this serialized access to shared resources, typically via locks/semaphores
As an advantage: data is really modified in place, less need to copy. (some performance gains)
B. On the other hand, functional code uses immutable data which does not have such issues. Data is readonly so there are no race conditions. Code can be easily parallelized. Results can be cached. Much easier to understand.
As a disadvantage: data is copied a lot in order to get "modifications".
See also: https://en.wikipedia.org/wiki/Referential_transparency
Imperative programming style was practiced in web development from 2005 all the way to 2013.
With imperative programming, we wrote out code that listed exactly what our application should do, step by step.
The functional programming style produces abstraction through clever ways of combining functions.
There is mention of declarative programming in the answers and regarding that I will say that declarative programming lists out some rules that we are to follow. We then provide what we refer to as some initial state to our application and we let those rules kind of define how the application behaves.
Now, these quick descriptions probably don’t make a lot of sense, so lets walk through the differences between imperative and declarative programming by walking through an analogy.
Imagine that we are not building software, but instead we bake pies for a living. Perhaps we are bad bakers and don’t know how to bake a delicious pie the way we should.
So our boss gives us a list of directions, what we know as a recipe.
The recipe will tell us how to make a pie. One recipe is written in an imperative style like so:
Mix 1 cup of flour
Add 1 egg
Add 1 cup of sugar
Pour the mixture into a pan
Put the pan in the oven for 30 minutes and 350 degrees F.
The declarative recipe would do the following:
1 cup of flour, 1 egg, 1 cup of sugar - initial State
Rules
If everything mixed, place in pan.
If everything unmixed, place in bowl.
If everything in pan, place in oven.
So imperative approaches are characterized by step by step approaches. You start with step one and go to step 2 and so on.
You eventually end up with some end product. So making this pie, we take these ingredients mix them, put it in a pan and in the oven and you got your end product.
In a declarative world, its different.In the declarative recipe we would separate our recipe into two separate parts, start with one part that lists the initial state of the recipe, like the variables. So our variables here are the quantities of our ingredients and their type.
We take the initial state or initial ingredients and apply some rules to them.
So we take the initial state and pass them through these rules over and over again until we get a ready to eat rhubarb strawberry pie or whatever.
So in a declarative approach, we have to know how to properly structure these rules.
So the rules we might want to examine our ingredients or state, if mixed, put them in a pan.
With our initial state, that doesn’t match because we haven’t yet mixed our ingredients.
So rule 2 says, if they not mixed then mix them in a bowl. Okay yeah this rule applies.
Now we have a bowl of mixed ingredients as our state.
Now we apply that new state to our rules again.
So rule 1 says if ingredients are mixed place them in a pan, okay yeah now rule 1 does apply, lets do it.
Now we have this new state where the ingredients are mixed and in a pan. Rule 1 is no longer relevant, rule 2 does not apply.
Rule 3 says if the ingredients are in a pan, place them in the oven, great that rule is what applies to this new state, lets do it.
And we end up with a delicious hot apple pie or whatever.
Now, if you are like me, you may be thinking, why are we not still doing imperative programming. This makes sense.
Well, for simple flows yes, but most web applications have more complex flows that cannot be properly captured by imperative programming design.
In a declarative approach, we may have some initial ingredients or initial state like textInput=“”, a single variable.
Maybe text input starts off as an empty string.
We take this initial state and apply it to a set of rules defined in your application.
If a user enters text, update text input. Well, right now that doesn’t apply.
If template is rendered, calculate the widget.
If textInput is updated, re render the template.
Well, none of this applies so the program will just wait around for an event to happen.
So at some point a user updates the text input and then we might apply rule number 1.
We may update that to “abcd”
So we just updated our text and textInput updates, rule number 2 does not apply, rule number 3 says if text input is update, which just occurred, then re render the template and then we go back to rule 2 thats says if template is rendered, calculate the widget, okay lets calculate the widget.
In general, as programmers, we want to strive for more declarative programming designs.
Imperative seems more clear and obvious, but a declarative approach scales very nicely for larger applications.
I think it's possible to express functional programming in an imperative fashion:
Using a lot of state check of objects and if... else/ switch statements
Some timeout/ wait mechanism to take care of asynchornousness
There are huge problems with such approach:
Rules/ procedures are repeated
Statefulness leaves chances for side-effects/ mistakes
Functional programming, treating functions/ methods like objects and embracing statelessness, was born to solve those problems I believe.
Example of usages: frontend applications like Android, iOS or web apps' logics incl. communication with backend.
Other challenges when simulating functional programming with imperative/ procedural code:
Race condition
Complex combination and sequence of events. For example, user tries to send money in a banking app. Step 1) Do all of the following in parallel, only proceed if all is good a) Check if user is still good (fraud, AML) b) check if user has enough balance c) Check if recipient is valid and good (fraud, AML) etc. Step 2) perform the transfer operation Step 3) Show update on user's balance and/ or some kind of tracking. With RxJava for example, the code is concise and sensible. Without it, I can imagine there'd be a lot of code, messy and error prone code
I also believe that at the end of the day, functional code will get translated into assembly or machine code which is imperative/ procedural by the compilers. However, unless you write assembly, as humans writing code with high level/ human-readable language, functional programming is the more appropriate way of expression for the listed scenarios
There seem to be many opinions about what functional programs and what imperative programs are.
I think functional programs can most easily be described as "lazy evaluation" oriented. Instead of having a program counter iterate through instructions, the language by design takes a recursive approach.
In a functional language, the evaluation of a function would start at the return statement and backtrack, until it eventually reaches a value. This has far reaching consequences with regards to the language syntax.
Imperative: Shipping the computer around
Below, I've tried to illustrate it by using a post office analogy. The imperative language would be mailing the computer around to different algorithms, and then have the computer returned with a result.
Functional: Shipping recipes around
The functional language would be sending recipes around, and when you need a result - the computer would start processing the recipes.
This way, you ensure that you don't waste too many CPU cycles doing work that is never used to calculate the result.
When you call a function in a functional language, the return value is a recipe that is built up of recipes which in turn is built of recipes. These recipes are actually what's known as closures.
// helper function, to illustrate the point
function unwrap(val) {
while (typeof val === "function") val = val();
return val;
}
function inc(val) {
return function() { unwrap(val) + 1 };
}
function dec(val) {
return function() { unwrap(val) - 1 };
}
function add(val1, val2) {
return function() { unwrap(val1) + unwrap(val2) }
}
// lets "calculate" something
let thirteen = inc(inc(inc(10)))
let twentyFive = dec(add(thirteen, thirteen))
// MAGIC! The computer still has not calculated anything.
// 'thirteen' is simply a recipe that will provide us with the value 13
// lets compose a new function
let doubler = function(val) {
return add(val, val);
}
// more modern syntax, but it's the same:
let alternativeDoubler = (val) => add(val, val)
// another function
let doublerMinusOne = (val) => dec(add(val, val));
// Will this be calculating anything?
let twentyFive = doubler(thirteen)
// no, nothing has been calculated. If we need the value, we have to unwrap it:
console.log(unwrap(thirteen)); // 26
The unwrap function will evaluate all the functions to the point of having a scalar value.
Language Design Consequences
Some nice features in imperative languages, are impossible in functional languages. For example the value++ expression, which in functional languages would be difficult to evaluate. Functional languages make constraints on how the syntax must be, because of the way they are evaluated.
On the other hand, with imperative languages can borrow great ideas from functional languages and become hybrids.
Functional languages have great difficulty with unary operators like for example ++ to increment a value. The reason for this difficulty is not obvious, unless you understand that functional languages are evaluated "in reverse".
Implementing a unary operator would have to be implemented something like this:
let value = 10;
function increment_operator(value) {
return function() {
unwrap(value) + 1;
}
}
value++ // would "under the hood" become value = increment_operator(value)
Note that the unwrap function I used above, is because javascript is not a functional language, so when needed we have to manually unwrap the value.
It is now apparent that applying increment a thousand times would cause us to wrap the value with 10000 closures, which is worthless.
The more obvious approach, is to actually directly change the value in place - but voila: you have introduced modifiable values a.k.a mutable values which makes the language imperative - or actually a hybrid.
Under the hood, it boils down to two different approaches to come up with an output when provided with an input.
Below, I'll try to make an illustration of a city with the following items:
The Computer
Your Home
The Fibonaccis
Imperative Languages
Task: Calculate the 3rd fibonacci number.
Steps:
Put The Computer into a box and mark it with a sticky note:
Field
Value
Mail Address
The Fibonaccis
Return Address
Your Home
Parameters
3
Return Value
undefined
and send off the computer.
The Fibonaccis will upon receiving the box do as they always do:
Is the parameter < 2?
Yes: Change the sticky note, and return the computer to the post office:
Field
Value
Mail Address
The Fibonaccis
Return Address
Your Home
Parameters
3
Return Value
0 or 1 (returning the parameter)
and return to sender.
Otherwise:
Put a new sticky note on top of the old one:
Field
Value
Mail Address
The Fibonaccis
Return Address
Otherwise, step 2, c/oThe Fibonaccis
Parameters
2 (passing parameter-1)
Return Value
undefined
and send it.
Take off the returned sticky note. Put a new sticky note on top of the initial one and send The Computer again:
Field
Value
Mail Address
The Fibonaccis
Return Address
Otherwise, done, c/o The Fibonaccis
Parameters
2 (passing parameter-2)
Return Value
undefined
By now, we should have the initial sticky note from the requester, and two used sticky notes, each having their Return Value field filled. We summarize the return values and put it in the Return Value field of the final sticky note.
Field
Value
Mail Address
The Fibonaccis
Return Address
Your Home
Parameters
3
Return Value
2 (returnValue1 + returnValue2)
and return to sender.
As you can imagine, quite a lot of work starts immediately after you send your computer off to the functions you call.
The entire programming logic is recursive, but in truth the algorithm happens sequentially as the computer moves from algorithm to algorithm with the help of a stack of sticky notes.
Functional Languages
Task: Calculate the 3rd fibonacci number. Steps:
Write the following down on a sticky note:
Field
Value
Instructions
The Fibonaccis
Parameters
3
That's essentially it. That sticky note now represents the computation result of fib(3).
We have attached the parameter 3 to the recipe named The Fibonaccis. The computer does not have to perform any calculations, unless somebody needs the scalar value.
Functional Javascript Example
I've been working on designing a programming language named Charm, and this is how fibonacci would look in that language.
fib: (n) => if (
n < 2 // test
n // when true
fib(n-1) + fib(n-2) // when false
)
print(fib(4));
This code can be compiled both into imperative and functional "bytecode".
The imperative javascript version would be:
let fib = (n) =>
n < 2 ?
n :
fib(n-1) + fib(n-2);
The HALF functional javascript version would be:
let fib = (n) => () =>
n < 2 ?
n :
fib(n-1) + fib(n-2);
The PURE functional javascript version would be much more involved, because javascript doesn't have functional equivalents.
let unwrap = ($) =>
typeof $ !== "function" ? $ : unwrap($());
let $if = ($test, $whenTrue, $whenFalse) => () =>
unwrap($test) ? $whenTrue : $whenFalse;
let $lessThen = (a, b) => () =>
unwrap(a) < unwrap(b);
let $add = ($value, $amount) => () =>
unwrap($value) + unwrap($amount);
let $sub = ($value, $amount) => () =>
unwrap($value) - unwrap($amount);
let $fib = ($n) => () =>
$if(
$lessThen($n, 2),
$n,
$add( $fib( $sub($n, 1) ), $fib( $sub($n, 2) ) )
);
I'll manually "compile" it into javascript code:
"use strict";
// Library of functions:
/**
* Function that resolves the output of a function.
*/
let $$ = (val) => {
while (typeof val === "function") {
val = val();
}
return val;
}
/**
* Functional if
*
* The $ suffix is a convention I use to show that it is "functional"
* style, and I need to use $$() to "unwrap" the value when I need it.
*/
let if$ = (test, whenTrue, otherwise) => () =>
$$(test) ? whenTrue : otherwise;
/**
* Functional lt (less then)
*/
let lt$ = (leftSide, rightSide) => () =>
$$(leftSide) < $$(rightSide)
/**
* Functional add (+)
*/
let add$ = (leftSide, rightSide) => () =>
$$(leftSide) + $$(rightSide)
// My hand compiled Charm script:
/**
* Functional fib compiled
*/
let fib$ = (n) => if$( // fib: (n) => if(
lt$(n, 2), // n < 2
() => n, // n
() => add$(fib$(n-2), fib$(n-1)) // fib(n-1) + fib(n-2)
) // )
// This takes a microsecond or so, because nothing is calculated
console.log(fib$(30));
// When you need the value, just unwrap it with $$( fib$(30) )
console.log( $$( fib$(5) ))
// The only problem that makes this not truly functional, is that
console.log(fib$(5) === fib$(5)) // is false, while it should be true
// but that should be solveable
https://jsfiddle.net/819Lgwtz/42/
I know this question is older and others already explained it well, I would like to give an example problem which explains the same in simple terms.
Problem: Writing the 1's table.
Solution: -
By Imperative style: =>
1*1=1
1*2=2
1*3=3
.
.
.
1*n=n
By Functional style: =>
1
2
3
.
.
.
n
Explanation in Imperative style we write the instructions more explicitly and which can be called as in more simplified manner.
Where as in Functional style, things which are self-explanatory will be ignored.
There are a few implementations of a hash or dictionary class in the Mathworks File Exchange repository. All that I have looked at use parentheses overloading for key referencing, e.g.
d = Dict;
d('foo') = 'bar';
y = d('foo');
which seems a reasonable interface. It would be preferable, though, if you want to easily have dictionaries which contain other dictionaries, to use braces {} instead of parentheses, as this allows you to get around MATLAB's (arbitrary, it seems) syntax limitation that multiple parentheses are not allowed but multiple braces are allowed, i.e.
t{1}{2}{3} % is legal MATLAB
t(1)(2)(3) % is not legal MATLAB
So if you want to easily be able to nest dictionaries within dictionaries,
dict{'key1'}{'key2'}{'key3'}
as is a common idiom in Perl and is possible and frequently useful in other languages including Python, then unless you want to use n-1 intermediate variables to extract a dictionary entry n layers deep, this seems a good choice. And it would seem easy to rewrite the class's subsref and subsasgn operations to do the same thing for {} as they previously did for (), and everything should work.
Except it doesn't when I try it.
Here's my code. (I've reduced it to a minimal case. No actual dictionary is implemented here, each object has one key and one value, but this is enough to demonstrate the problem.)
classdef TestBraces < handle
properties
% not a full hash table implementation, obviously
key
value
end
methods(Access = public)
function val = subsref(obj, ref)
% Re-implement dot referencing for methods.
if strcmp(ref(1).type, '.')
% User trying to access a method
% Methods access
if ismember(ref(1).subs, methods(obj))
if length(ref) > 1
% Call with args
val = obj.(ref(1).subs)(ref(2).subs{:});
else
% No args
val = obj.(ref.subs);
end
return;
end
% User trying to access something else.
error(['Reference to non-existant property or method ''' ref.subs '''']);
end
switch ref.type
case '()'
error('() indexing not supported.');
case '{}'
theKey = ref.subs{1};
if isequal(obj.key, theKey)
val = obj.value;
else
error('key %s not found', theKey);
end
otherwise
error('Should never happen')
end
end
function obj = subsasgn(obj, ref, value)
%Dict/SUBSASGN Subscript assignment for Dict objects.
%
% See also: Dict
%
if ~strcmp(ref.type,'{}')
error('() and dot indexing for assignment not supported.');
end
% Vectorized calls not supported
if length(ref.subs) > 1
error('Dict only supports storing key/value pairs one at a time.');
end
theKey = ref.subs{1};
obj.key = theKey;
obj.value = value;
end % subsasgn
end
end
Using this code, I can assign as expected:
t = TestBraces;
t{'foo'} = 'bar'
(And it is clear that the assignment work from the default display output for t.) So subsasgn appears to work correctly.
But I can't retrieve the value (subsref doesn't work):
t{'foo'}
??? Error using ==> subsref
Too many output arguments.
The error message makes no sense to me, and a breakpoint at the first executable line of my subsref handler is never hit, so at least superficially this looks like a MATLAB issue, not a bug in my code.
Clearly string arguments to () parenthesis subscripts are allowed, since this works fine if you change the code to work with () instead of {}. (Except then you can't nest subscript operations, which is the object of the exercise.)
Either insight into what I'm doing wrong in my code, any limitations that make what I'm doing unfeasible, or alternative implementations of nested dictionaries would be appreciated.
Short answer, add this method to your class:
function n = numel(obj, varargin)
n = 1;
end
EDIT: The long answer.
Despite the way that subsref's function signature appears in the documentation, it's actually a varargout function - it can produce a variable number of output arguments. Both brace and dot indexing can produce multiple outputs, as shown here:
>> c = {1,2,3,4,5};
>> [a,b,c] = c{[1 3 5]}
a =
1
b =
3
c =
5
The number of outputs expected from subsref is determined based on the size of the indexing array. In this case, the indexing array is size 3, so there's three outputs.
Now, look again at:
t{'foo'}
What's the size of the indexing array? Also 3. MATLAB doesn't care that you intend to interpret this as a string instead of an array. It just sees that the input is size 3 and your subsref can only output 1 thing at a time. So, the arguments mismatch. Fortunately, we can correct things by changing the way that MATLAB determines how many outputs are expected by overloading numel. Quoted from the doc link:
It is important to note the significance of numel with regards to the
overloaded subsref and subsasgn functions. In the case of the
overloaded subsref function for brace and dot indexing (as described
in the last paragraph), numel is used to compute the number of
expected outputs (nargout) returned from subsref. For the overloaded
subsasgn function, numel is used to compute the number of expected
inputs (nargin) to be assigned using subsasgn. The nargin value for
the overloaded subsasgn function is the value returned by numel plus 2
(one for the variable being assigned to, and one for the structure
array of subscripts).
As a class designer, you must ensure that the value of n returned by
the built-in numel function is consistent with the class design for
that object. If n is different from either the nargout for the
overloaded subsref function or the nargin for the overloaded subsasgn
function, then you need to overload numel to return a value of n that
is consistent with the class' subsref and subsasgn functions.
Otherwise, MATLAB produces errors when calling these functions.
And there you have it.