Index: polemy/eval.d
==================================================================
--- polemy/eval.d
+++ polemy/eval.d
@@ -112,20 +112,35 @@
 import std.typetuple;
 Value eval(AST e, Table ctx, bool splitCtx, Layer lay)
 {
 	return e.match(
 		(StrLiteral e)
-		{
-			return new StrValue(e.data);
+		{
+			Value v = new StrValue(e.data);
+			if( lay == "@v" )
+				return v;
+			else
+				return (cast(FunValue)ctx.get(lay, "(system)", e.pos)).call(e.pos, "@v", [v]);
 		},
 		(IntLiteral e)
 		{
-			return new IntValue(e.data);
+			Value v = new IntValue(e.data);
+			if( lay == "@v" )
+				return v;
+			else // are these "@v"s appropriate???
+				return (cast(FunValue)ctx.get(lay, "(system)", e.pos)).call(e.pos, "@v", [v]);
 		},
 		(VarExpression e)
 		{
-			return ctx.get(e.var, lay, e.pos);
+			try {
+				return ctx.get(e.var, lay, e.pos);
+			} catch( RuntimeException ) {
+				// rise
+				return (cast(FunValue)ctx.get(lay, "(system)", e.pos)).call(e.pos, "@v", 
+					[ctx.get(e.var, "@v", e.pos)]
+				);
+			}
 		},
 		(LayeredExpression e)
 		{
 			return eval(e.expr, ctx, false, e.lay);
 		},
@@ -216,10 +231,15 @@
 	fib(10);`).val, new IntValue(BigInt(89)));
 }
 
 unittest
 {
-	assert_throw!Throwable( evalString(`@s "+"=fun(x,y){x-y};@s(1+2)`) );
-	assert_eq( evalString(`@s "+"=fun(x,y){x-y};1+2`).val, new IntValue(BigInt(3)) );
-	assert_eq( evalString(`@s "+"=fun(x,y){@v(@s(x)-@s(y))};1+2`).val, new IntValue(BigInt(3)) );
-	assert_eq( evalString(`@s "+"=fun(x,y){@v(@s(x)-@s(y))};@s(1+2)`).val, new IntValue(BigInt(-1)) );
+	assert_throw!Throwable( evalString(`@@s(x){x}; @s "+"=fun(x,y){x-y};@s(1+2)`) );
+	assert_eq( evalString(`@@s(x){x}; @s "+"=fun(x,y){x-y};1+2`).val, new IntValue(BigInt(3)) );
+	assert_eq( evalString(`@@s(x){x}; @s "+"=fun(x,y){@v(@s(x)-@s(y))};1+2`).val, new IntValue(BigInt(3)) );
+	assert_eq( evalString(`@@s(x){x}; @s "+"=fun(x,y){@v(@s(x)-@s(y))};@s(1+2)`).val, new IntValue(BigInt(-1)) );
+}
+
+unittest
+{
+	assert_eq( evalString(`@@t = fun(x){x+1}; @t(123)`).val, new IntValue(BigInt(124)) );
 }

Index: polemy/parse.d
==================================================================
--- polemy/parse.d
+++ polemy/parse.d
@@ -74,36 +74,63 @@
 	AST Declaration() // returns null if it is not a declaration
 	{
 		/// Declaration ::=
 		///    ["@" Layer|"let"|"var"|"def"] Var "=" Expression ([";"|"in"] Body?)?
 		///  | ["@" Layer|"let"|"var"|"def"] Var "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)?
+		///  | ["@" "@" Layer "=" Expression ([";"|"in"] Body?)?
+		///  | ["@" "@" Layer "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)?
 
 		auto pos = currentPosition();
 		string layer = "";
+		bool layerRiseDecl = false;
 
 		if( tryEat("@") )
 		{
 			layer = "@" ~ eatId("after @", AllowQuoted);
-			if( tryEat("(") )
-				return null; // @lay(...) expression, not a declaration
-		}
-
-		string kwd = layer;
-		if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") )
-			return null; // none of {@lay, let, var, def} occurred, it's not a declaration
-
-		auto varpos = currentPosition();
-		string var = eatId("after "~kwd, AllowQuoted); // name of the declared variable
-
-		auto e = tryEat("(")
-			? parseLambdaAfterOpenParen(varpos)  // let var ( ...
-			: (eat("=", "after "~kwd), E(0));    // let var = ...
-
-		if( moreDeclarationExists() )
-			return new LetExpression(pos, var, layer, e, Body());
+			if( layer == "@@" )
+			{
+				layer = "@" ~ eatId("after @@", AllowQuoted);
+				layerRiseDecl = true;
+			}
+			else
+			{
+				if( tryEat("(") )
+					return null; // @lay(...) expression, not a declaration
+			}
+		}
+
+		// [TODO] Refactor
+		if( layerRiseDecl )
+		{
+			string kwd = "@" ~ layer;
+			string var = layer;
+
+			auto e = tryEat("(")
+				? parseLambdaAfterOpenParen(pos)  // let var ( ...
+				: (eat("=", "after "~kwd), E(0)); // let var = ...
+			if( moreDeclarationExists() )
+				return new LetExpression(pos, var, "(system)", e, Body());
+			else
+				return new LetExpression(pos, var, "(system)", e, new VarExpression(pos, var));
+		}
 		else
-			return new LetExpression(pos, var, layer, e, new VarExpression(varpos, var));
+		{
+			string kwd = layer;
+			if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") )
+				return null; // none of {@lay, let, var, def} occurred, it's not a declaration
+
+			auto varpos = currentPosition();
+			string var = eatId("after "~kwd, AllowQuoted); // name of the declared variable
+
+			auto e = tryEat("(")
+				? parseLambdaAfterOpenParen(varpos)  // let var ( ...
+				: (eat("=", "after "~kwd), E(0));    // let var = ...
+			if( moreDeclarationExists() )
+				return new LetExpression(pos, var, layer, e, Body());
+			else
+				return new LetExpression(pos, var, layer, e, new VarExpression(varpos, var));
+		}
 	}
 
 	AST TopLevelExpression()
 	{
 		/// TopLevelExpression ::= Expression ([";"|"in"] Body?)?
@@ -406,6 +433,9 @@
 	assert_eq(parseString(`def foo(x) { x+1 }; foo`),
 		let("foo", "",
 			fun(["x"], call(var("+"), var("x"), intl(1))),
 			var("foo"))
 	);
+
+	assert_eq(parseString(`@@type ( x ) { x }`),
+		let("@type", "(system)", fun(["x"], var("x")), var("@type")) );
 }