<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -32,7 +32,5 @@ updateFile updFn ps = do
   liftIO $ updFn f cnt
   return WyNull
 
-defp n l = M.insert n (WyPrimitive n l)
-
 asString (WyString s) = return s
 asString x            = get &gt;&gt;= appErr1 (\y -&gt; &quot;A string was expected, got &quot; ++ y) x</diff>
      <filename>haskell/src/fileio.hs</filename>
    </modified>
    <modified>
      <diff>@@ -85,15 +85,15 @@ module Foundation (
 
   // Accepts either a string or a symbol. Returns true if it corresponds
   // to a known binding in the current environment, false otherwise.
-  def defined? expression (
+  def defined? expr (
     primitive 'defined?'
   )
 
-  def empty? expression (
+  def empty? expr (
     primitive 'empty?'
   )
 
-  def isa? expression (
+  def isa? expr1 expr2 (
     primitive 'isa?'
   )
 
@@ -124,7 +124,7 @@ module Foundation (
     primitive '&gt;='
   )
 
-  def (!) lexpr rexpr (
+  def (!) expr (
     primitive '!'
   )
 
@@ -144,7 +144,7 @@ module Foundation (
     primitive '+'
   )
 
-  def (-) lexpr rexpr (
+  def (-) lexpr? rexpr (
     primitive '-'
   )
 
@@ -212,7 +212,7 @@ module Foundation (
 
   macro (`appl ^ `sub~) (
     if (applic? appl) (
-      `( ($ (wyId (fnName appl))) ($^ (params appl &lt;&lt; sub )) )
+      `( ($ (wyId (fnName appl))) ($^ (params appl &lt;&lt; sub)) )
     )(
       `( ($appl) ($^ [sub]) )
     )
@@ -221,7 +221,7 @@ module Foundation (
   // Control structures
   //
 
-  def if cond body contra (
+  def if cond body contra? (
     primitive 'if'
   )
 
@@ -291,7 +291,7 @@ module Foundation (
   )
   macropx (`a &gt;&gt; `b) 1 ((&gt;&gt;) $a $b)
 
-  def (@!) ref val (
+  def (@!) ref pos val (
     primitive '@!'
   )
 
@@ -311,7 +311,7 @@ module Foundation (
     primitive 'toS'
   )
 
-  def slice list start end (
+  def slice list start end? (
     primitive 'slice'
   )
 </diff>
      <filename>haskell/src/foundation.wy</filename>
    </modified>
    <modified>
      <diff>@@ -13,6 +13,7 @@ import Control.Monad.State
 import Data.Foldable(foldrM)
 import Text.ParserCombinators.Parsec(parse)
 
+import qualified Data.Sequence as S
 import qualified Data.Map as M
 import Data.IORef(newIORef, readIORef)
 import qualified Data.Traversable as T
@@ -48,45 +49,65 @@ evalWy (WyId idn pos) | otherwise = do
     Nothing -&gt; throwError $ UnknownRef (&quot;Unknown reference: &quot; ++ idn) pos
     Just v  -&gt; return v
     
-evalWy (WyApplic fn ps pos) = put pos &gt;&gt; eval fn &gt;&gt;= apply ps
+evalWy wa@(WyApplic fn vals pos) = put pos &gt;&gt; do
+  efn &lt;- eval fn
+  let ps = params efn
+  case adjust WyNull WyList ps vals $ length vals - (fst $ unslurps ps) of
+    Nothing   -&gt; paramErr ps vals
+    Just adjv -&gt; if (length adjv == length ps) 
+                   -- normal application
+                   then apply adjv vals efn
+                   -- partial application
+                   else let rmndr = drop (length adjv) ps
+                            newps = vals ++ map (flip WyId pos) rmndr
+                        in return $ WyLambda rmndr (WyApplic fn newps pos) S.empty
+  where 
+    params (WyLambda ps _ _) = ps
+    params (WyPrimitive _ ps _) = ps
+    params (WyCont _) = [&quot;c&quot;]
 
--- evalWy (WyStmt xs) = liftM last $ applyMacros xs &gt;&gt;= (\x -&gt; trace (show x) (return x)) &gt;&gt;= mapM evalWy
 evalWy (WyStmt xs) = liftM last $ applyMacros xs &gt;&gt;= mapM evalWy
 evalWy (WyBlock xs) = liftM last $ mapM evalWy xs
+evalWy wy = get &gt;&gt;= appErr1 (\x -&gt; &quot;Don't know how to eval: &quot; ++ x) wy
 
 eval ast = evalWy ast &gt;&gt;= liftIO . readRef
 
 -- Function application, either primitive or lambdas
-apply:: [WyType] -&gt; WyType -&gt; Eval WyType
-apply vals (WyPrimitive n fn) = fn vals
-apply vals wl@(WyLambda _ _ _) = mapM evalWy vals &gt;&gt;= applyDirect wl
-apply vals (WyCont c) = liftM head (mapM evalWy vals) &gt;&gt;= c
-apply ps other = get &gt;&gt;= appErr1 (\x -&gt; &quot;Don't know how to apply: &quot; ++ x ++ &quot; &quot; ++ show ps) other
+apply:: [WyType] -&gt; [WyType] -&gt; WyType -&gt; Eval WyType
+
+apply adjv vals (WyPrimitive n _ fn) = fn vals -- TODO primitives should use adjusted parameters
+apply adjv vals wl@(WyLambda _ _ _) = mapM evalWy adjv &gt;&gt;= applyDirect wl
+apply adjv vals (WyCont c) = liftM head (mapM evalWy vals) &gt;&gt;= c
+apply _ vals other = get &gt;&gt;= appErr1 (\x -&gt; &quot;Don't know how to apply: &quot; ++ x ++ &quot; &quot; ++ show vals) other
 
 -- Application of lambdas from argument list and evaluated values
-applyDirect (WyLambda ps body lenv) vals = 
-    localM (const $ buildFrame ps vals lenv) $ evalWy body
-  where 
-    buildFrame ps vs e  =
-      case adjust WyNull WyList ps vs $ length vs - (fst $ unslurps ps) of
-        Nothing   -&gt; get &gt;&gt;= appErr1 (\x -&gt; &quot;Wrong number of arguments in function call: &quot; ++ x ++ &quot; for &quot; ++ show ps) (WyList vs)
-        Just adjV -&gt; liftIO $ envStack (snd $ unslurps ps) adjV e
+
+applyDirect wl@(WyLambda ps body lenv) vals =
+  let buildFrame ps vs e = liftIO $ envStack (snd $ unslurps ps) vs e
+  in localM (const $ buildFrame ps vals lenv) $ evalWy body
+
+paramErr ps vs = get &gt;&gt;= 
+  appErr (&quot;Wrong number of arguments in function call: &quot; ++ 
+          (show . length $ vs) ++ &quot; for &quot; ++ (show . length $ ps))
 
 -- Adjusts the values provided for an application to a function's arguments. Handles
 -- optionals and varargs. Needs a zero to set missing optionals value and a list
 -- wrapper function to wrap varargs.
 adjust :: a -&gt; ([a] -&gt; a) -&gt; [String] -&gt; [a] -&gt; Int -&gt; Maybe [a]
+
 adjust z l (p:ps) (v:vs) dif 
   | last p == '?' &amp;&amp; dif &lt;= 0 = liftM (z :) $ adjust z l ps (v:vs) dif
   | last p == '?' &amp;&amp; dif &gt; 0  = liftM (v :) $ adjust z l ps vs (dif - 1)
-  | last p == '~' &amp;&amp; dif &gt;= 0 =
+  | last p == '~' &amp;&amp; dif &gt; 0 =
       let s = slurp (v:vs) dif 
       in liftM (l s :) $ adjust z l ps (drop (length s - 1) vs) (dif - length s)
+  | last p == '~' &amp;&amp; dif &lt;= 0 = liftM (l [] :) $ adjust z l ps (v:vs) dif
   | otherwise = liftM (v :) $ adjust z l ps vs dif
 
 adjust z l (p:ps) [] dif 
   | last p == '?' &amp;&amp; dif &lt;= 0 || last p == '~' &amp;&amp; dif == 0 = liftM (z :) $ adjust z l ps [] dif
 adjust z l [] [] dif | dif == 0 = Just []
+adjust z l (p:ps) [] dif | dif &lt; 0 = Just []
 adjust z l _  _  x = Nothing
 
 -- Consumes values matched to a vararg</diff>
      <filename>haskell/src/interpr.hs</filename>
    </modified>
    <modified>
      <diff>@@ -28,13 +28,13 @@ import Wy.FileIO
 defWy ps = do
   env &lt;- ask
   defName &lt;- extractId $ head ps
+  params  &lt;- mapM extractId . tail . init $ ps
   case last ps of
     (WyStmt [WyApplic (WyId n _) [WyString primName] pos]) | n == &quot;primitive&quot; -&gt; do
       case M.lookup primName $ primitives M.empty of
         Nothing -&gt; throwError $ ArgumentErr (&quot;Unknown primitive referenced in def: &quot; ++ primName) pos
-        Just x  -&gt; liftIO $ varUpdate env defName x
-    x -&gt; do params &lt;- mapM extractId $ tail $ init ps
-            let wl = WyLambda params (last ps) env
+        Just x  -&gt; liftIO $ varUpdate env defName (toPrimitive x params)
+    x -&gt; do let wl = WyLambda params (last ps) env
             liftIO $ varInsert defName wl env
             return wl
 
@@ -87,10 +87,11 @@ basePrim f =
     fn   &lt;- liftIO $ varValue fnNm env
     fstP &lt;- evalWy . head $ tail ps
     lstP &lt;- astList fstP
+    let lps = (fstP : (tail . tail) ps)
     case fn of
       Just f  -&gt; case lstP of
-                   Just l  -&gt; apply l f
-                   Nothing -&gt; apply (fstP : (tail . tail) ps) f
+                   Just l  -&gt; apply l l f
+                   Nothing -&gt; apply lps lps f
       Nothing -&gt; get &gt;&gt;= (appErr $ &quot;Unknown function: &quot; ++ fnNm) ) $
 
   defp &quot;try&quot; (\ps -&gt;
@@ -167,12 +168,15 @@ basePrim f =
           v &lt;- liftIO . readRef $ M.findWithDefault WyNull (WyString &quot;type&quot;) m
           if (v == WyString errstr)
             then liftM Just $ applyDirect (last xs) 
-              [WyMap $ 
-                M.insert (WyString &quot;source&quot;) (WyString $ wySrcFile pos) $
-                M.insert (WyString &quot;line&quot;) (WyInt $ wySrcLine pos) $
-                M.insert (WyString &quot;column&quot;) (WyInt $ wySrcCol pos) $
-                M.insert (WyString &quot;message&quot;) (WyString $ errstr ++ &quot;: &quot; ++ msg) m]
+              [WyMap $                
+                M.insert (WyString &quot;message&quot;) (WyString $ errstr ++ &quot;: &quot; ++ msg) $
+                addSrcInfo m pos]
             else return Nothing
+        addSrcInfo m (WySourcePos l c f) = 
+          M.insert (WyString &quot;source&quot;) (WyString f) $
+          M.insert (WyString &quot;line&quot;) (WyInt l) $
+          M.insert (WyString &quot;column&quot;) (WyInt c) m
+        addSrcInfo m NoPos = m
 
 arithmPrim f = 
   defp &quot;+&quot; (opEvalM wyPlus) $
@@ -418,8 +422,6 @@ stdIOPrim f =
 --
 -- Common support functions
 
-defp n l = M.insert n (WyPrimitive n l)
-
 extractName (WyId i _) = return i
 extractName (WyStmt [x]) = extractName x
 extractName (WyString s) = return s</diff>
      <filename>haskell/src/prim.hs</filename>
    </modified>
    <modified>
      <diff>@@ -44,7 +44,7 @@ trim = trimR . trimR
   where trimR = reverse . dropWhile isSpace
 
 main = do params &lt;- getArgs
-          p &lt;- newIORef $ M.insert &quot;def&quot; (WyPrimitive &quot;def&quot; defWy) M.empty
+          p &lt;- newIORef $ M.insert &quot;def&quot; (WyPrimitive &quot;def&quot; [&quot;name&quot;, &quot;params~&quot;, &quot;body&quot;] defWy) M.empty
           m &lt;- newIORef M.empty
           let blankEnv = S.empty |&gt; Frame p m False
           e &lt;-  wyInterpr blankEnv &quot;foundation&quot; foundationText</diff>
      <filename>haskell/src/repl.hs</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,8 @@ module Wy.Types
     extractId,
     wyPlus, wyMinus, wyDiv, wyMult, wyIsA,
     WyEnv, Frame(..), macroValue, varValue, macroUpdate, varInsert, varUpdate, envStack, envAdd, envAddMod,
-    Eval, localM, localIO, runEval, appErr, appErr1, appErr2
+    Eval, localM, localIO, runEval, appErr, appErr1, appErr2,
+    WyNativeDef, toPrimitive, defp
   ) where
 
 import qualified Data.Sequence as S
@@ -39,7 +40,7 @@ data WyType = WyString String
             | WyMap (M.Map WyType WyType)
             | WyLambda [String] WyType WyEnv
             | WyMacro { macroPattern:: WyType, macroBody:: WyType, macroPriority:: Integer, macroEnv:: WyEnv }
-            | WyPrimitive String ([WyType] -&gt; Eval WyType)
+            | WyPrimitive String [String] ([WyType] -&gt; Eval WyType)
             | WyCont (WyType -&gt; Eval WyType)
             | WyModule String (M.Map String WyType) (M.Map String WyType)
 
@@ -117,7 +118,7 @@ showWy (WyList s) = liftM (\x -&gt; &quot;[&quot; ++ (intercalate &quot;,&quot; x) ++ &quot;]&quot;) $ mapM showW
 showWy (WyMap s) = showRet s
 showWy (WyLambda ss ast env) = return $ &quot;lambda(&quot; ++ (show ss) ++ &quot;, &quot; ++ (show ast) ++ &quot;)&quot;
 showWy (WyMacro p b _ env) = return $ &quot;macro(&quot; ++ (show p) ++ &quot;, &quot; ++ (show b) ++ &quot;)&quot;
-showWy (WyPrimitive n _) = return $ &quot;&lt;primitive &quot; ++ (show n) ++ &quot;&gt;&quot;
+showWy (WyPrimitive n _ _) = return $ &quot;&lt;primitive &quot; ++ (show n) ++ &quot;&gt;&quot;
 showWy (WyCont c) = return &quot;&lt;cont&gt;&quot;
 showWy (WyModule n _ _) = return $ &quot;module &quot; ++ n ++ &quot; ..&quot;
 showWy (WyId s _) = return s
@@ -160,9 +161,9 @@ wyIsA WyNull WyNull = True
 wyIsA (WyList _) (WyList _) = True
 wyIsA (WyMap _) (WyMap _) = True
 wyIsA (WyLambda _ _ _) (WyLambda _ _ _) = True
-wyIsA (WyLambda _ _ _) (WyPrimitive _ _) = True
-wyIsA (WyPrimitive _ _) (WyLambda _ _ _) = True
-wyIsA (WyPrimitive _ _) (WyPrimitive _ _) = True
+wyIsA (WyLambda _ _ _) (WyPrimitive _ _ _) = True
+wyIsA (WyPrimitive _ _ _) (WyLambda _ _ _) = True
+wyIsA (WyPrimitive _ _ _) (WyPrimitive _ _ _) = True
 wyIsA (WyMacro _ _ _ _) (WyMacro _ _ _ _) = True
 wyIsA (WyCont _) (WyCont _) = True
 wyIsA (WyModule _ _ _) (WyModule _ _ _) = True
@@ -259,7 +260,7 @@ data WyError = UnknownRef String WySourcePos
 
 appErr2 txtFn x1 x2 pos = liftM2 txtFn (showWyE x1) (showWyE x2) &gt;&gt;= (throwError . (flip ArgumentErr $ pos))
 appErr1 txtFn x pos = liftM txtFn (showWyE x) &gt;&gt;= (throwError . (flip ArgumentErr $ pos))
-appErr txtFn pos = throwError $ ArgumentErr txtFn pos
+appErr txt pos = throwError $ ArgumentErr txt pos
 
 instance Error WyError where
   noMsg  = Undef &quot;Undefined error. Sucks to be you.&quot;
@@ -275,3 +276,12 @@ localM f a = do
   env &lt;- ask
   newEnv &lt;- f env
   local (const newEnv) a
+
+--
+-- Helpers for primitives definition
+
+data WyNativeDef = WyNativeDef String ([WyType] -&gt; Eval WyType)
+toPrimitive (WyNativeDef n fn) args = WyPrimitive n args fn
+
+defp n l = M.insert n (WyNativeDef n l)
+</diff>
      <filename>haskell/src/types.hs</filename>
    </modified>
    <modified>
      <diff>@@ -20,6 +20,9 @@ testAdjustFixed = TestCase $ assertEqual
   &quot;Should leave fixed params unchanged&quot; (Just [WyInt 1, WyInt 2]) $ adjust WyNull WyList [&quot;a&quot;, &quot;b&quot;] [WyInt 1, WyInt 2] 0
 testAdjustFixedErr = TestCase $ assertEqual
   &quot;Should fail for insufficent fixed values&quot; Nothing $ adjust WyNull WyList [&quot;a&quot;, &quot;b&quot;] [WyInt 1] 0
+testAdjustFailTooManyParams = TestCase $ assertEqual
+  &quot;Should fail with too many parameters&quot; Nothing $ 
+  adjust WyNull WyList [&quot;a&quot;, &quot;b&quot;] [WyInt 0, WyInt 1, WyInt 2] (-1)
 testAdjustFixedErr2 = TestCase $ assertEqual
   &quot;Should fail for too many fixed values&quot; Nothing $ adjust WyNull WyList [&quot;a&quot;, &quot;b&quot;] [WyInt 1, WyInt 2, WyInt 3] 1
 testAdjustOneOpt = TestCase $ assertEqual
@@ -48,7 +51,7 @@ testAdjustInterEndMissing = TestCase $ assertEqual
 
 adjustOptTests = TestList [testAdjustEmpty, testAdjustFixed, testAdjustFixedErr, testAdjustOneOpt, 
   testAdjustOneOptMissing, testAdjustTwoOpt, testAdjustTwoOptOneMiss, testAdjustTwoOptTwoMiss,
-  testAdjustInter]
+  testAdjustInter, testAdjustFailTooManyParams]
 
 testAdjustEmptySlurpy = TestCase $ assertEqual
   &quot;Should nullify missing slurpy&quot; (Just [WyInt 0, WyNull]) $ 
@@ -59,12 +62,15 @@ testAdjustEndingSlurpy = TestCase $ assertEqual
 testAdjustMiddleSlurpy = TestCase $ assertEqual
   &quot;Should fill middle slurpy&quot; (Just [WyInt 0, WyList [WyInt 1, WyInt 2], WyInt 3]) $ 
   adjust WyNull WyList [&quot;a&quot;, &quot;b~&quot;, &quot;c&quot;] [WyInt 0, WyInt 1, WyInt 2, WyInt 3] 2
+testAdjustEmptyMiddleSlurpy = TestCase $ assertEqual
+  &quot;Should insert empty middle slurpy&quot; (Just [WyInt 0, WyList [], WyInt 3]) $ 
+  adjust WyNull WyList [&quot;a&quot;, &quot;b~&quot;, &quot;c&quot;] [WyInt 0, WyInt 3] 0
 testAdjustFailFixedMissSlurpy = TestCase $ assertEqual
-  &quot;Should fail with slurpy but missing fixed params&quot; Nothing $ 
+  &quot;Should fail with slurpy but missing fixed params&quot; (Just [WyInt 0]) $ 
   adjust WyNull WyList [&quot;a&quot;, &quot;b~&quot;, &quot;c&quot;] [WyInt 0] (-1)
 
 adjustSlurpyTests = TestList [testAdjustEmptySlurpy, testAdjustEndingSlurpy, testAdjustMiddleSlurpy, 
-  testAdjustFailFixedMissSlurpy]
+  testAdjustEmptyMiddleSlurpy, testAdjustFailFixedMissSlurpy]
 
 --
 -- Pattern matching</diff>
      <filename>haskell/test/hunit.hs</filename>
    </modified>
    <modified>
      <diff>@@ -35,7 +35,7 @@ describe &quot;Function isa?&quot; (
 )
 
 describe &quot;Last argument macro ^ &quot; (
-  it &quot;should factor in operations&quot; (((+) 1 2 ^ 3+4) == 10)
+  it &quot;should factor in operations&quot; (((+) 1 ^ 3+4) == 8)
   it &quot;should work with a macro application&quot; ^ 3 + 4 == 7
   it &quot;should be chainable&quot; (((+) 1 ^ (+) 2 ^ (+) 3 4) == 10)
   it &quot;should work in a macro definition&quot; (</diff>
      <filename>test/stdlib.wy</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>942a46d8c0808971422c43710252c9a10ab27d38</id>
    </parent>
  </parents>
  <author>
    <name>Matthieu Riou</name>
    <email>matthieu.riou@c3-carbon.com</email>
  </author>
  <url>http://github.com/matthieu/witty/commit/4cb7aa98bf60a89ece106f57c10f41078f3c02a9</url>
  <id>4cb7aa98bf60a89ece106f57c10f41078f3c02a9</id>
  <committed-date>2009-09-27T21:02:55-07:00</committed-date>
  <authored-date>2009-09-27T21:02:55-07:00</authored-date>
  <message>Partial application as a default behavior.</message>
  <tree>5208a43a1c686306160d28cb828c53ec70cd641e</tree>
  <committer>
    <name>Matthieu Riou</name>
    <email>matthieu.riou@c3-carbon.com</email>
  </committer>
</commit>
