Skip to content

Instantly share code, notes, and snippets.

@bitcrazed
Forked from ckirkendall/clojure-match.clj
Last active March 7, 2020 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bitcrazed/41939974879bd5056337 to your computer and use it in GitHub Desktop.
Save bitcrazed/41939974879bd5056337 to your computer and use it in GitHub Desktop.
Language Comparison: Simple AST in Clojure, F#, Ocaml, Scala, Clojure, Ruby, C++, C#, Go, Haskell and others
(use '[clojure.core.match :only [match]])
(defn evaluate [env [sym x y]]
(match [sym]
['Number] x
['Add] (+ (evaluate env x) (evaluate env y))
['Multiply] (* (evaluate env x) (evaluate env y))
['Variable] (env x)))
(def environment {"a" 3, "b" 4, "c" 5})
(def expression-tree '(Add (Variable "a") (Multiply (Number 2) (Variable "b"))))
(def result (evaluate environment expression-tree))
(defprotocol Expression
(evaluate [e env] ))
(deftype Number1 [x])
(deftype Add [x y] )
(deftype Multiply [x y])
(deftype Variable [x])
(extend-protocol Expression
Number1 (evaluate [e env] (.x e ) )
Add (evaluate [e env] (+ (evaluate (.x e) env) (evaluate (.y e) env)))
Multiply (evaluate [e env] (* (evaluate (.x e) env) (evaluate (.y e) env)))
Variable (evaluate [e env] (env (.x e))))
(def environment {"a" 3, "b" 4, "c" 5})
(def expression-tree (Add. (Variable. "a") (Multiply. (Number1. 2) (Variable. "b"))))
(def result (evaluate expression-tree environment))
#include <string>
#include <iostream>
#include <map>
#include <memory>
typedef std::map <std::string, int> Variables;
struct Expr
{
virtual ~Expr() {}
virtual int eval (Variables&) = 0;
};
struct Multiply : public Expr
{
std::unique_ptr<Expr> e1, e2;
Multiply (Expr* lhs, Expr* rhs) : e1 (lhs), e2 (rhs) {}
int eval (Variables& env) { return e1->eval (env) * e2->eval (env); }
};
struct Add : public Expr
{
std::unique_ptr<Expr> e1, e2;
Add (Expr* lhs, Expr* rhs) : e1 (lhs), e2 (rhs) {}
int eval (Variables& env) { return e1->eval (env) + e2->eval (env); }
};
struct Constant : public Expr
{
int value;
Constant (int val) : value (val) {}
int eval (Variables&) { return value; }
};
struct Variable : public Expr
{
std::string varName;
Variable (const std::string& name) : varName (name) {}
int eval (Variables& env) { return env [varName]; }
};
int main (int argc, char** argv)
{
Variables env;
env["a"] = 3;
env["b"] = 4;
env["c"] = 5;
Add tree (new Variable ("a"),
new Multiply (new Constant (2),
new Variable ("b")));
std::cout << tree.eval (env) << std::endl;
}
using System;
using Env = System.Collections.Generic.Dictionary<string, int>;
delegate int Expr(Env e);
public class Program
{
public static void Main()
{
Func<string, Expr> Var = s => env => env[s];
Func<int, Expr> Num = i => env => i;
Func<Expr, Expr, Expr> Add = (x, y) => env => x(env) + y(env);
Func<Expr, Expr, Expr> Mul = (x, y) => env => x(env) * y(env);
var expr = Add(Var("a"), Mul(Num(2), Var("b")));
Console.WriteLine(expr(new Env { { "a", 3 }, { "b", 4 }, { "c", 5 } }));
}
}
type Expression =
| Number of int
| Add of Expression * Expression
| Multiply of Expression * Expression
| Variable of string
let rec Evaluate (env:Map<string,int>) exp =
match exp with
| Number n -> n
| Add (x, y) -> Evaluate env x + Evaluate env y
| Multiply (x, y) -> Evaluate env x * Evaluate env y
| Variable id -> env.[id]
let environment = Map.ofList [ "a", 1; "b", 2; "c", 3 ]
let expressionTree1 = Add(Variable "a", Multiply(Number 2, Variable "b"))
let result = Evaluate environment expressionTree1
package main
import "fmt"
type Add struct{a, b interface{}}
type Mul struct{a, b interface{}}
func eval(env map[string]int, e interface{}) int {
switch v := e.(type) {
case int: return v
case string: return env[v]
case Add: return eval(env, v.a) + eval(env, v.b)
case Mul: return eval(env, v.a) * eval(env, v.b)
}
return 0
}
func main() {
env := map[string]int{"a":3, "b":4, "c":5}
ast := Add{"a", Mul{2, "b"}}
fmt.Println(eval(env, ast))
}
import Data.Map
data Expression =
Number Int
| Add Expression Expression
| Multiply Expression Expression
| Variable String
evaluate :: Map String Int -> Expression -> Int
evaluate env exp =
case exp of
Number x -> x
Add x y -> evaluate env x + evaluate env y
Multiply x y -> evaluate env x * evaluate env y
Variable x -> findWithDefault 0 x env
environment = fromList([("a",3), ("b",4), ("c",7)])
expressionTree = Add (Variable "a") (Multiply (Number 2) (Variable "b"))
result = evaluate environment expressionTree
import Data.Map
data Expression =
Number Int
| Add Expression Expression
| Multiply Expression Expression
| Variable String
evaluate :: Map String Int -> Expression -> Int
evaluate env (Number x) = x
evaluate env (Add x y) = evaluate env x + evaluate env y
evaluate env (Multiply x y) = evaluate env x * evaluate env y
evaluate env (Variable x) = findWithDefault 0 x env
environment = fromList([("a",3), ("b",4), ("c",7)])
expressionTree = Add (Variable "a") (Multiply (Number 2) (Variable "b"))
result = evaluate environment expressionTree
#pragma indent
using Nemerle.Extensions;
using System.Collections.Generic;
variant Ast
| Number { val : int }
| Add { left : Ast; right : Ast }
| Multiply { left : Ast; right : Ast }
| Variable { name : string }
def eval(env, expr)
match(expr)
| Ast.Number(val) => val
| Add(l, r) => eval(env, l) + eval(env, r)
| Multiply(l, r) => eval(env, l) * eval(env, r)
| Variable(name) => env[name]
def environment = Dictionary() <- ["a" = 3, "b" = 4, "c" = 5];
def expr = Ast.Add(Ast.Variable("a"), Ast.Multiply(Ast.Number(2), Ast.Variable("b")));
def result = eval(environment, expr);
type expression =
Number of int
| Add of expression * expression
| Multiply of expression * expression
| Variable of string
let rec evaluate env = function
| Number n -> n
| Add (x, y) -> evaluate env x + evaluate env y
| Multiply (x, y) -> evaluate env x * evaluate env y
| Variable id -> env id
let environment = function "a" -> 3 | "b" -> 4 | "c" -> 5
let expressiontree1 = Add(Variable "a", Multiply(Number 2, Variable "b"))
let result = evaluate environment expressiontree1
Number = lambda env, n: n
Add = lambda env, a, b: evaluate(env, a) + evaluate(env, b)
Multiply = lambda env, a, b: evaluate(env, a) * evaluate(env, b)
Variable = lambda env, x: env[x]
evaluate = lambda env, expr: expr[0](env, *expr[1:])
expression_tree = (Add, (Variable, 'a'),
(Multiply, (Number, 2),
(Variable, 'b')))
environment = {'a': 3, 'b': 4, 'c': 5}
print evaluate(environment, expression_tree)
def evaluate(env, exp)
keyword, a, b = exp
case keyword
when :number; a
when :variable; env[a]
when :add; evaluate(env, a) + evaluate(env, b)
when :multiply; evaluate(env, a) * evaluate(env, b)
end
end
ExpressionTree = [:add, [:variable, :a], [:multiply, [:number, 2], [:variable, :b]]]
Env = { a: 3, b: 4, c: 5 }
puts evaluate(Env, ExpressionTree)
Number = lambda { |env, num| num }
Variable = lambda { |env, var| env[var] }
Add = lambda { |env, a, b| evaluate(env, a) + evaluate(env, b) }
Multiply = lambda { |env, a, b| evaluate(env, a) * evaluate(env, b) }
def evaluate(env, exp)
op, *args = exp
op.(env, *args)
end
ExpressionTree = [Add, [Variable, :a], [Multiply, [Number, 2], [Variable, :b]]]
Env = { a: 3, b: 4, c: 5 }
puts evaluate(Env, ExpressionTree)
abstract class Expression
case class Number(i: Int) extends Expression
case class Add(x: Expression, y: Expression) extends Expression
case class Multiply(x: Expression, y: Expression) extends Expression
case class Variable(id: Symbol) extends Expression
object Maths extends App {
val environment = Map('a -> 1,
'b -> 2,
'c -> 3)
def evaluate(env: Map[Symbol, Int], exp: Expression): Int = exp match {
case Number(n: Int) => n
case Add(x, y) => evaluate(env, x) + evaluate(env, y)
case Multiply(x, y) => evaluate(env, x) * evaluate(env, y)
case Variable(id: Symbol) => env(id)
}
val expressionTree1 = Add(Variable('a), Multiply(Number(2), Variable('b)))
println(evaluate(environment, expressionTree1))
}
import java.util.*;
public class Eval {
static int evaluate(Map env, Expression exp){
if(exp instanceof Variable){ return (Integer)env.get(((Variable)exp).x); }
else if(exp instanceof Number){ return ((Number)exp).x; }
else if(exp instanceof Multiply){ return evaluate(env, ((Multiply)exp).x)*evaluate(env, ((Multiply)exp).y); }
else if(exp instanceof Add){ return evaluate(env, ((Add)exp).x)+evaluate(env, ((Add)exp).y); }
return 0;
}
public static void main(String[] args){
Map env=new HashMap();
env.put("a", 3);
env.put("b", 4);
env.put("c", 5);
Expression expressionTree=new Add(new Variable("a"), new Multiply(new Number(2), new Variable("b")));
System.out.println(evaluate(env, expressionTree));
}
}
abstract class Expression {}
class Number extends Expression{
int x;
Number(int x){ this.x=x; }
}
class Add extends Expression{
Expression x; Expression y;
Add(Expression x, Expression y){ this.x=x; this.y=y; }
}
class Multiply extends Add{
Multiply(Expression x, Expression y){ super(x, y); }
}
class Variable extends Expression{
String x;
Variable(String x){ this.x=x; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment