How can I implement a lossless CRDT using Gun? - gun

How do I create a CRDT using Gun?
For instance, if I want to implement an grow-only array, where each element points to the next, how do I solve conflicts?
To simplify, let's create this scenario, where Alice and Bob are cooperating.
The array contains 3 elements, [a, b, d].
The internal representation of this array would be a linked list like this:
a => b => c
(of course, the internal representation would be something like {value: 'a', next: { value: 'b' next: { value: 'c' }}}), but I think you get my point with the terser notation.
Alice now wants to insert element c between b and d.
Concurrently, Bob wants to insert element C between b and d.
Concurrently, they have this internal representation of the array:
Alice: a => b => c => d
Bob: a => b => C => d
When they join the CRDT, they would converge to either one of the following values:
a => b => c => C => d
or
a => b => C => c => d
No matter what, a) both of them would converge on the same value and b) they would not lose each other's data.
Can we achieve this using Gun?
(This question is a simplification and follow-up question to https://github.com/amark/gun/issues/602)

Yes.
Here is a demo of code doing just that from a few years ago:
https://youtu.be/rci89p0o2wQ
You can create any other CRDT as a data structure on top of GUN's base CRDT.
We even did a whole cartoon explainer on generic algorithms for this type of stuff:
https://gun.eco/explainers/school/class.html
(Or see a more detailed explanation for a case-specific implementation, by the wonderful Martin Kleppmann starting at https://youtu.be/yCcWpzY8dIA?t=29m36s )
I haven't seen anybody implement RGA specifically on top of GUN, but given how short the code you sent over, it should be pretty easy. (Although the "delete" would need to be a null tombstone, but that is fine)
It is probably easiest to start by looking at the counter CRDT for "how to start saving data to GUN with a custom extension", a grow-only CRDT in just 12 lines of code:
https://gun.eco/docs/Counter
You note that it is very basic, RGA would be similar, you'd probably have some GUN extension (just a JS method/function, that makes it easier for developers to use) like
Gun.chain.rga = function(...
Then internally, like with the counter, you'd call gun.put( or gun.set( or whatever other commands to save data to the graph (put and set are themselves just extensions like RGA is, nothing fancy here) where you'd build/construct a graph/tree/table, or you could be lazy and just do something like:
// fictional code
var myData = {
rgaTree: {left: {}, right: {}}
}
myData.rgaTree.left.next = myData.rgaTree.right;
myData.rgaTree.right.prev = myData.rgaTree.left;
// yes! circular references are supported!
gun.put(myData);
Obviously you might want to be more detailed and control the UUIDs with the cuids and stuff, but you get the point.
There is no reason to actually replace HAM CRDT directly or "inject" a CRDT along side it, just #pgte would model the CRDT's data structure on GUN (probably with a nice easy API via a GUN extension), then you'd also have that extension support a callback, which if passed you'd gun.get(... through the RGA graph/tree and run the various RGA logic before spitting the result back out to the developer. This tree can be dynamically mutated concurrently inside of GUN by many peers, like Alice and Bob!
Then, GUN will save that dynamically changing and updating data to disk via one of (many) storage engines (such as IPFS!) so IPFS can host the persistence of data over time, and GUN can manage the O(1) tree lookups that are the mutable/changing/dynamic tree/graph/index structures.

Related

Updating Records in Elm ( what happened to the old one?)

Ok first off please see the post below:
Updating a record in Elm
I'm more curious as to how that is actually possible since that makes the record a variable in effect, something functional programming tries to avoid?
What happened to my old bill? Someone basically deleted my x = 4 and made a new one x = boo_far?
Functional programming avoids mutation. In Elm, records are not mutated, they are copied.
Even saying that they are copied is a bit of a misrepresentation. They are not fully cloned byte for byte. That would be horribly inefficient. Their internal structure is more graph-like, allowing for efficient pointer-based operations that effectively extend the underlying structures without mutating already-existing nodes and edges when you perform operations that copy into a new record.
Conceptually speaking, it may help to think of it this way: Once you copy into a new record value, the old one sticks around forever. However, our computers don't have infinite memory, and those old values may often go permanently unused, so we leave it to Javascript's garbage collector to clean up those old pointers.
Consider the example in the answer given by #timothyclifford:
-- Create Bill Gates
billGates = { age = 100, name = "gates" }
-- Copy to Bill Nye
billNye = { bill | name = "Nye" }
-- Copy to a younger Bill Nye
youngBillNye = { billNye | age = 22 }
The internal representation could be thought of like this:
Conceptually, you can think of those living in perpetuity. However, let's say that billGates gets selected for garbage deletion because it is no longer being referenced (e.g. its frame is popped from the stack). The billGates pointer is deleted and the name=="gates" node is deleted, but all other nodes and edges remain untouched:

Does elm have haskell like lens or something similar?

In haskell I use the lens library. Is there something similar in elm?
If I have this elm data structure, how could I add 3 to test.a.b.
test = {
a = {
b = 5
}
}
In haskell I would write: test & a.b ~% (+3).
In haskell I can write makeLenses ''RecordName and automatically generate lenses, does elm have that?
Sort of. It has the Focus library. It would allow you to say something like:
Focus.update (a => b) ((+) 3) test
...to add three to test.a.b. It has two drawbacks that spring to mind. The first is that you have to create your lenses by hand. This isn't a big deal. For your test record above, to create a lens (or focus) by hand, you first need a getter function, which is trivial:
.a
And then a map function, which can apply a function to a given test:
\f test = { test | a = f test.a }
Now you can combine those two to make a focus:
a =
Focus.create
.a
(\f test = { test | a = f test.a })
Do the same for b:
b =
Focus.create
.b
(\f a = { a | b = f a.b })
And now you can combine these two foci with (a => b) and that lets you make the Focus.update call shown above. So there's a bit of boilerplate, but it's no great hardship, and you can do nested gets/sets/updates to your heart's content.
The bigger limitation is, you can't do prisms. So if there's a Maybe involved in your path, you're blocked. Back to doing the nested update the long-long-longhand way.
Why are there no prisms? Because they need higher kinded types, and Elm doesn't have those. (Yet?)
So the answer's yes & no. You can have something Lens-like, but don't expect the full power of Haskell lenses.
Update: Looks like I was wrong on my last point - Monacle provides Prisms. I didn't think it was possible. I stand corrected!

What is difference between functional and imperative programming languages?

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.

How to use SmallCheck in Haskell?

I am trying to use SmallCheck to test a Haskell program, but I cannot understand how to use the library to test my own data types. Apparently, I need to use the Test.SmallCheck.Series. However, I find the documentation for it extremely confusing. I am interested in both cookbook-style solutions and an understandable explanation of the logical (monadic?) structure. Here are some questions I have (all related):
If I have a data type data Person = SnowWhite | Dwarf Integer, how do I explain to smallCheck that the valid values are Dwarf 1 through Dwarf 7 (or SnowWhite)? What if I have a complicated FairyTale data structure and a constructor makeTale :: [Person] -> FairyTale, and I want smallCheck to make FairyTale-s from lists of Person-s using the constructor?
I managed to make quickCheck work like this without getting my hands too dirty by using judicious applications of Control.Monad.liftM to functions like makeTale. I couldn't figure out a way to do this with smallCheck (please explain it to me!).
What is the relationship between the types Serial, Series, etc.?
(optional) What is the point of coSeries? How do I use the Positive type from SmallCheck.Series?
(optional) Any elucidation of what is the logic behind what should be a monadic expression, and what is just a regular function, in the context of smallCheck, would be appreciated.
If there is there any intro/tutorial to using smallCheck, I'd appreciate a link. Thank you very much!
UPDATE: I should add that the most useful and readable documentation I found for smallCheck is this paper (PDF). I could not find the answer to my questions there on the first look; it is more of a persuasive advertisement than a tutorial.
UPDATE 2: I moved my question about the weird Identity that shows up in the type of Test.SmallCheck.list and other places to a separate question.
NOTE: This answer describes pre-1.0 versions of SmallCheck. See this blog post for the important differences between SmallCheck 0.6 and 1.0.
SmallCheck is like QuickCheck in that it tests a property over some part of the space of possible types. The difference is that it tries to exhaustively enumerate a series all of the "small" values instead of an arbitrary subset of smallish values.
As I hinted, SmallCheck's Serial is like QuickCheck's Arbitrary.
Now Serial is pretty simple: a Serial type a has a way (series) to generate a Series type which is just a function from Depth -> [a]. Or, to unpack that, Serial objects are objects we know how to enumerate some "small" values of. We are also given a Depth parameter which controls how many small values we should generate, but let's ignore it for a minute.
instance Serial Bool where series _ = [False, True]
instance Serial Char where series _ = "abcdefghijklmnopqrstuvwxyz"
instance Serial a => Serial (Maybe a) where
series d = Nothing : map Just (series d)
In these cases we're doing nothing more than ignoring the Depth parameter and then enumerating "all" possible values for each type. We can even do this automatically for some types
instance (Enum a, Bounded a) => Serial a where series _ = [minBound .. maxBound]
This is a really simple way of testing properties exhaustively—literally test every single possible input! Obviously there are at least two major pitfalls, though: (1) infinite data types will lead to infinite loops when testing and (2) nested types lead to exponentially larger spaces of examples to look through. In both cases, SmallCheck gets really large really quickly.
So that's the point of the Depth parameter—it lets the system ask us to keep our Series small. From the documentation, Depth is the
Maximum depth of generated test values
For data values, it is the depth of nested constructor applications.
For functional values, it is both the depth of nested case analysis and the depth of results.
so let's rework our examples to keep them Small.
instance Serial Bool where
series 0 = []
series 1 = [False]
series _ = [False, True]
instance Serial Char where
series d = take d "abcdefghijklmnopqrstuvwxyz"
instance Serial a => Serial (Maybe a) where
-- we shrink d by one since we're adding Nothing
series d = Nothing : map Just (series (d-1))
instance (Enum a, Bounded a) => Serial a where series d = take d [minBound .. maxBound]
Much better.
So what's coseries? Like coarbitrary in the Arbitrary typeclass of QuickCheck, it lets us build a series of "small" functions. Note that we're writing the instance over the input type---the result type is handed to us in another Serial argument (that I'm below calling results).
instance Serial Bool where
coseries results d = [\cond -> if cond then r1 else r2 |
r1 <- results d
r2 <- results d]
these take a little more ingenuity to write and I'll actually refer you to use the alts methods which I'll describe briefly below.
So how can we make some Series of Persons? This part is easy
instance Series Person where
series d = SnowWhite : take (d-1) (map Dwarf [1..7])
...
But our coseries function needs to generate every possible function from Persons to something else. This can be done using the altsN series of functions provided by SmallCheck. Here's one way to write it
coseries results d = [\person ->
case person of
SnowWhite -> f 0
Dwarf n -> f n
| f <- alts1 results d ]
The basic idea is that altsN results generates a Series of N-ary function from N values with Serial instances to the Serial instance of Results. So we use it to create a function from [0..7], a previously defined Serial value, to whatever we need, then we map our Persons to numbers and pass 'em in.
So now that we have a Serial instance for Person, we can use it to build more complex nested Serial instances. For "instance", if FairyTale is a list of Persons, we can use the Serial a => Serial [a] instance alongside our Serial Person instance to easily create a Serial FairyTale:
instance Serial FairyTale where
series = map makeFairyTale . series
coseries results = map (makeFairyTale .) . coseries results
(the (makeFairyTale .) composes makeFairyTale with each function coseries generates, which is a little confusing)
If I have a data type data Person = SnowWhite | Dwarf Integer, how do I explain to smallCheck that the valid values are Dwarf 1 through Dwarf 7 (or SnowWhite)?
First of all, you need to decide which values you want to generate for each depth. There's no single right answer here, it depends on how fine-grained you want your search space to be.
Here are just two possible options:
people d = SnowWhite : map Dwarf [1..7] (doesn't depend on the depth)
people d = take d $ SnowWhite : map Dwarf [1..7] (each unit of depth increases the search space by one element)
After you've decided on that, your Serial instance is as simple as
instance Serial m Person where
series = generate people
We left m polymorphic here as we don't require any specific structure of the underlying monad.
What if I have a complicated FairyTale data structure and a constructor makeTale :: [Person] -> FairyTale, and I want smallCheck to make FairyTale-s from lists of Person-s using the constructor?
Use cons1:
instance Serial m FairyTale where
series = cons1 makeTale
What is the relationship between the types Serial, Series, etc.?
Serial is a type class; Series is a type. You can have multiple Series of the same type — they correspond to different ways to enumerate values of that type. However, it may be arduous to specify for each value how it should be generated. The Serial class lets us specify a good default for generating values of a particular type.
The definition of Serial is
class Monad m => Serial m a where
series :: Series m a
So all it does is assigning a particular Series m a to a given combination of m and a.
What is the point of coseries?
It is needed to generate values of functional types.
How do I use the Positive type from SmallCheck.Series?
For example, like this:
> smallCheck 10 $ \n -> n^3 >= (n :: Integer)
Failed test no. 5.
there exists -2 such that
condition is false
> smallCheck 10 $ \(Positive n) -> n^3 >= (n :: Integer)
Completed 10 tests without failure.
Any elucidation of what is the logic behind what should be a monadic expression, and what is just a regular function, in the context of smallCheck, would be appreciated.
When you are writing a Serial instance (or any Series expression), you work in the Series m monad.
When you are writing tests, you work with simple functions that return Bool or Property m.
While I think that #tel's answer is an excellent explanation (and I wish smallCheck actually worked the way he describes), the code he provides does not work for me (with smallCheck version 1). I managed to get the following to work...
UPDATE / WARNING: The code below is wrong for a rather subtle reason. For the corrected version, and details, please see this answer to the question mentioned below. The short version is that instead of instance Serial Identity Person one must write instance (Monad m) => Series m Person.
... but I find the use of Control.Monad.Identity and all the compiler flags bizarre, and I have asked a separate question about that.
Note also that while Series Person (or actually Series Identity Person) is not actually exactly the same as functions Depth -> [Person] (see #tel's answer), the function generate :: Depth -> [a] -> Series m a converts between them.
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts, UndecidableInstances #-}
import Test.SmallCheck
import Test.SmallCheck.Series
import Control.Monad.Identity
data Person = SnowWhite | Dwarf Int
instance Serial Identity Person where
series = generate (\d -> SnowWhite : take (d-1) (map Dwarf [1..7]))

Juggling multiple object instances

This question is coded in pseudo-PHP, but I really don't mind what language I get answers in (except for Ruby :-P), as this is purely hypothetical. In fact, PHP is quite possibly the worst language to be doing this type of logic in. Unfortunately, I have never done this before, so I can't provide a real-world example. Therefore, hypothetical answers are completely acceptable.
Basically, I have lots of objects performing a task. For this example, let's say each object is a class that downloads a file from the Internet. Each object will be downloading a different file, and the downloads are run in parallel. Obviously, some objects may finish downloading before others. The actual grabbing of data may run in threads, but that is not relevant to this question.
So we can define the object as such:
class DownloaderObject() {
var $url = '';
var $downloading = false;
function DownloaderObject($v){ // constructor
$this->url = $v;
start_downloading_in_the_background(url=$this->$url, callback=$this->finished);
$this->downloading = true;
}
function finished() {
save_the_data_somewhere();
$this->downloading = false;
$this->destroy(); // actually destroys the object
}
}
Okay, so we have lots of these objects running:
$download1 = new DownloaderObject('http://somesite.com/latest_windows.iso');
$download2 = new DownloaderObject('http://somesite.com/kitchen_sink.iso');
$download3 = new DownloaderObject('http://somesite.com/heroes_part_1.rar');
And we can store them in an array:
$downloads = array($download1, $download2, $download3);
So we have an array full of the downloads:
array(
1 => $download1,
2 => $download2,
3 => $download3
)
And we can iterate through them like this:
print('Here are the downloads that are running:');
foreach ($downloads as $d) {
print($d->url . "\n");
}
Okay, now suppose download 2 finishes, and the object is destroyed. Now we should have two objects in the array:
array(
1 => $download1,
3 => $download3
)
But there is a hole in the array! Key #2 is being unused. Also, if I wanted to start a new download, it is unclear where to insert the download into the array. The following could work:
$i = 0;
while ($i < count($downloads) - 1) {
if (!is_object($downloads[$i])) {
$downloads[$i] = new DownloaderObject('http://somesite.com/doctorwho.iso');
break;
}
$i++;
}
However, that is terribly inefficient (and while $i++ loops are nooby). So, another approach is to keep a counter.
function add_download($url) {
global $downloads;
static $download_counter;
$download_counter++;
$downloads[$download_counter] = new DownloaderObject($url);
}
That would work, but we still get holes in the array:
array(
1 => DownloaderObject,
3 => DownloaderObject,
7 => DownloaderObject,
13 => DownloaderObject
)
That's ugly. However, is that acceptable? Should the array be "defragmented", i.e. the keys rearranged to eliminate blank spaces?
Or is there another programmatic structure I should be aware of? I want a structure that I can add stuff to, remove stuff from, refer to keys in a variable, iterate through, etc., that is not an array. Does such a thing exist?
I have been coding for years, but this question has bugged me for very many of those years, and I am still not aware of an answer. This may be obvious to some programmers, but is extremely non-trivial to me.
The problem with PHP's "associative arrays" is that they aren't arrays at all, they're Hashmaps. Having holes there is perfectly fine. You might look at a linked list, as well, but a Hashmap seems perfectly suited to what you're doing.
What is maintaining your array of downloaders?
If you encapsulate the array in a class that is notified by the downloader when it is finished you won't have to worry about stale references to destroyed objects.
This class can manage the organisation of the array internally and present an interface to its users that looks more like an iterator than an array.
"$i++ loops" are nooby, but only because the code becomes much clearer if you use a for loop:
$i = 0;
while ($i < count($downloads) - 1) {
if (!is_object($downloads[$i])) {
$downloads[$i] = new DownloaderObject('http://somesite.com/doctorwho.iso');
break;
}
$i++;
}
Becomes
for($i=0;$i<count($downloads)-1;++$i){
if (!is_object($downloads[$i])) {
$downloads[$i] = new DownloaderObject('http://somesite.com/doctorwho.iso');
break;
}
}
Coming from a C# perspective, my first thought would be that you need a different data structure to an array - you need to think about the problem using a higher-level data structure. Perhaps a Queue, List or Stack would suit your purposes better?
The short answer to your question is that in PHP arrays are used for almost everything and you rarely end up using other data structures. Having holes in your array indexes isn't anything to worry about. In other programming languages such as Java you have a more diverse set of data structures to choose from: Sets, Hashes, Lists, Vectors and more. It seems that you would also need to have a closer interaction between the Array and DownloaderObject class. Just because the object $download2 has "destroyed()" itself the array will maintain a reference to that object.
Some good answers to this question, which reflect on the relative experience on the answerers. Thank you very much — they proved very educational.
I posted this question nearly three years ago. In hindsight, I can see my knowledge in that area was severely lacking. The biggest problem I had was that I was coming from a PHP perspective, which does not have the ability to arbitrarily pop elements. Something the other answers to this question helped me to discover was that a fundamentally superior model is 'linked lists'.
For C, I wrote a blog post about linked lists which contains code samples (too numerous to post here) but would neatly fill the original question's use case.
For PHP, a linked list implementation appears here, which I have never tried, but imagine it would also be the right way to deal with the above.
Interestingly, Python lists contain the pop() method which, unlike PHP's array_pop(), can pop arbitrary elements and keep everything in order. For example:
>>> x = ['baa', 'ram', 'ewe'] # our starting point
>>> x[1] # making sure element 1 is 'ram'
'ram'
>>> x.pop(1) # let's arbitrarily pop an element in the middle
'ram'
>>> x # the one we popped ('ram') is now gone
['baa', 'ewe']
>>> x[1] # and there are no holes: item 2 has become item 1
'ewe'