01 Einführung 02 RWD 03 JavaScript 04 DOM 05 Async 06 SVG 07 Node 08 ModularWeb 09 PWA 10 Vue 11 WebAssembly 12 Security

Übung 03 - JavaScript

3.1 Funktionen in JavaScript
Schreiben Sie eine Funktion identity_function(), die ein Argument als Parameter entgegen nimmt und eine Funktion zurück gibt, die dieses Argument zurück gibt.
                        
    function identity_function(param){
        return function(){
            return param;
        }
    }
                        
                    
Schreiben Sie eine Addier-Funktion addf(), so dass addf(x)(y) genau x + y zurück gibt.
                        
    function addf(x){
        return function(y){
            return x+y;
        }
    }
                        
                    
Schreiben Sie eine Funktion applyf(), die aus einer binären Funktion wie add(x,y) eine Funktion addf berechnet, die mit zwei Aufrufen das gleiche Ergebnis liefert.
                        
    function applyf(f){
        return function(x){
            return function(y){
                return f(x,y);
            }
        }
    }
                        
                    
Schreiben Sie eine Funktion curry(), die eine binäre Funktion und ein Argument nimmt, um daraus eine Funktion zu erzeugen, die ein zweites Argument entgegen nimmt.
                        
    function curry(f, arg){
        return function (argtwo){
            return f(arg, argtwo)
        }
    }
                        
                    
Erzeugen Sie die inc-Funktion mit Hilfe einer der Funktionen addf, applyf und curry aus den letzten Aufgaben, ohne die Funktion inc() selbst zu implementieren.
                        
    // Version 1
    function inc1(arg){
        return addf(arg)(1);
    }
    // Version 2
    function inc2(arg){
        return applyf(add)(arg)(1);
    }
    // Version 3
    function inc3(arg){
        return curry(add, arg)(1);
    }
                        
                    
Schreiben Sie eine Funktion methodize(), die eine binäre Funktion (z.B. add, mul) in eine unäre Methode verwandelt. Nach Number.prototype.add = methodize(add); soll (3).add(4) genau 7 ergeben.
                        
    function methodize(f){
        return function(x){
            return f(this,x)
        }
    }
                        
                    
Schreiben Sie eine Funktion demethodize(), die eine unäre Methode (z.B. add, mul) in eine binäre Funktion umwandelt. demethodize(Number.prototype.add)(5, 6) soll 11 ergeben.
                        
    function demethodize(f){
        return function(x, y){
            return f.call(x,y);
        }
    }
                        
                    
Schreiben Sie eine Funktion twice(), die eine binäre Funktion in eine unäre Funktion umwandelt, die den einen Parameter zweimal weiter reicht.
                        
function twice(f){
    return function(x){
        return f(x,x);
    }
}
                        
                    
Schreiben Sie eine Funktion composeu(), die zwei unäre Funktionen in eine einzelne unäre Funktion transformiert, die beide nacheinander aufruft.
                        
    function composeu(f1, f2){
        return function(x){
            return f2(f1(x));
        }
    }
                        
                    
Schreiben Sie eine Funktion composeb(), die zwei binäre Funktionen in eine einzelne Funktion transformiert, die beide nacheinander aufruft.
                        
    function composeb(f1, f2){
        return function(x,y,z){
            return f2(f1(x,y),z);
        }
    }
                        
                    
Schreiben Sie eine Funktion once(), die einer anderen Funktion nur einmal erlaubt, aufgerufen zu werden.
                        
    function once(func) {
        return function () {
            var f = func;
            func = null;
            return f.apply(this, arguments);
        };
    }
                        
                    
3.2 Advanced Functional JavaScript Programming
Make a function that makes a publish/subscribe object. It will reliably deliver all publications to all subscribers in the right order.
                        
    function pubsub(){
        var subs = []
        return {
            subscribe: function (f){
                subs.push(f);
            },
            publish: function (arg){
                for(let s of subs){
                    s(arg);
                }
            }
        }
    }
                        
                    
Make a factory that makes functions that generate unique symbols.
                        
    function gensymf(sym) {
        var counter = 0;
        return function () {
            counter = counter + 1;
            return `${sym}${counter - 1}`;
        }
    }
                        
                    
Make a function that returns a function that will return the next fibonacci number.
                        
    function fibonaccif(x, y) {
        return function() {
            var next = x;
            x = y;
            y += next;
            return next;
        }
    }
                        
                    
Write a function that adds from many invocations, until it sees an empty invocation.
                        
    function addg(a){
        if(!a){
            return undefined;
        }
        return function plus(b){
            if(!b){
                return a;
            }
            if(b){
                a += b;
                return plus;
            }
        }
    }
                        
                    
Write a function that will take a binary function and apply it to many invocations.
                        
    function applyg(f) {
        return function (a) {
            if (!a) return a;

            return function cont(b) {
                if (!b) return a;
                a = f(a, b);
                return cont;
            }
        }
    }
                        
                    
Write a function m that takes a value and an optional source string and returns them in an object.
                        
    function m(value, source){
        return {"value": value, "source": (source || value).toString()};
    }
                        
                    
Write a function addm that takes two m objects and returns an m object.
                        
    function addm(m1, m2){
        return m(m1.value+m2.value, m1.source + m2.source);
    }
                        
                    
Write a function binarymf that takes a binary function and a string and returns a function that acts on m objects.
                        
    function binarymf(f, s) {
        return function (m1, m2) {
            return m(f(m1.value, m2.value), `(${m1.value}${s}${m2.value})`);
        }
    }
                        
                    
Modify function binarymf so that the functions it produces can accept arguments that are either numbers or m objects.
                        
    function binarymf2(f, s){
        return function(m1, m2){
            if(m1.value){
                return m(f(m1.value, m2.value), `(${m1.value}${s}${m2.value})`);
            }else{
                return m(f(m1,m2), `(${m1}${s}${m2})`);
            }
        }
    }
                        
                    
Write function unarymf, which is like binarymf except that it acts on unary functions.
                        
    function unarymf(f, s){
        return function(a){
            return m(f(a), `(${s} ${a})`);
        }
    }
                        
                    
Write a function that takes the lengths of two sides of a triangle and computes the length of the hypotenuse. (Hint: c2 = a2 + b2)
                        
    function hyp(a, b) {
        return Math.sqrt(square(a) + square(b));
    }
                        
                    
Write a function that evaluates array expressions.
                        
    function exp(arr) {
        function iter(subarr){
            for(let i in subarr){
                if(subarr[i] instanceof Array){
                    subarr[i] = iter(subarr[i]);
                }else{
                    if(typeof subarr[1] === "number"){
                        return calc(subarr);
                    }
                }
            }
            return subarr;
        }
        function calc(arri){
            if(arri.length === 2){
                return arri[0](arri[1]);
            }
            if(arri.length === 3){
                return arri[0](arri[1], arri[2]);
            }
        }
        while(arr.some(e => e instanceof Array)){
            iter(arr);
        }
        return calc(arr);
    }
                        
                    
Make a function that stores a value in a variable.
                        
    function store(n) {
        variable = n;
    }
                        
                    
Make a function that takes a binary function, two functions that provide operands, and a function that takes the result.
                        
    function quatre(binary, op1, op2, res){
        res(binary(op1, op2));
    }
                        
                    
Make a function that takes a unary function, and returns a function that takes an argument and a callback.
                        
    function unaryc(unary){
        return function (arg, cb){
            cb(unary(arg));
        }
    }
                        
                    
Make a function that takes a binary function, and returns a function that takes two arguments and a callback.
                        
    function binaryc(binary){
        return function (a, b, cb){
            cb(binary(a,b));
        }
    }