[Omake] test/object/Test14

Aleksey Nogin nogin at metaprl.org
Thu Aug 2 15:52:08 PDT 2007


On 02.08.2007 12:07, Jason Hickey wrote:

> All that being said, we could think about some way to get what you want 
> specifically for foreach.  Basically, a way to do the following 
> translation.
> 
>    Original:
> 
>       A.foreach(key => exp)
> 
>    Translates to:
> 
>       apply(key) =
>          exp
>       public.obj = $(this)
>       A.foreach(key => ...)
>           obj.apply($(key))
>           export
>       this = $(obj)

Right. There are two approaches here:

- The one you proposed - making the ValBody evaluation happen in the 
parent object (no matter where it was passed to).

- Creating a mechanism for defining "shallow methods" that act like 
functions w.r.t. to the "this" namespace.

Here is a simple hack for "shallow methods": allow a method to have a 
"type" of "() -> args -> ..." (a 0-arity function returning an actual 
function). When a method like this is applied to >0 arguments, _both_ 
arrows are applied - the first with the method call conventions, and the 
second with the normal function call conventions.

Under this convention, the Sequence object would contain:

    foreach() =
       private.This = $(this)
       f(body, v) =
          export
          sequence-map($(body), $(v), $(private.This))

which would finally make foreach methods work exactly like I want them 
to! A proof-of-concept implementation is attached.

While the particular way of implementing "shallow methods" may seem too 
big of a hack, I think the general concept is sound. We just need a good 
way of embedding it into the language.

> In any case, I think we should undo the changes to the hoisting code.

Done (sort of). There were some strange artifacts in that code (such as 
messing up the static environment instead of simply keeping the original 
one, failing to export phonies and implicit rules, etc) - fixes to those 
were not reverted. Basically, I made path-export equivalent to normal 
exports in everything unrelated to the "this" namespace and head 
variable value.
-------------- next part --------------
Index: src/eval/omake_eval.ml
===================================================================
--- src/eval/omake_eval.ml	(revision 11542)
+++ src/eval/omake_eval.ml	(working copy)
@@ -1808,11 +1808,17 @@
    let pos = string_pos "eval_apply_string_export_exp" pos in
    match eval_value venv pos v with
       ValFun (_, env, params, body, export) ->
-         let args = List.map (eval_string_exp true venv pos) args in
-         let venv_new = venv_add_args venv_obj pos loc env params args in
-         let venv_new, result = eval_sequence_exp venv_new pos body in
-         let venv = add_path_exports venv venv_obj venv_new pos path export in
-            venv, result
+         if params = [] && args <> [] then
+            let venv_new = venv_add_args venv_obj pos loc env [] [] in
+            let venv_new, result = eval_sequence_exp venv_new pos body in
+            let venv = add_path_exports venv venv_obj venv_new pos path export in
+               eval_apply_string_export_exp venv venv pos loc result args
+         else
+            let args = List.map (eval_string_exp true venv pos) args in
+            let venv_new = venv_add_args venv_obj pos loc env params args in
+            let venv_new, result = eval_sequence_exp venv_new pos body in
+            let venv = add_path_exports venv venv_obj venv_new pos path export in
+               venv, result
     | ValPrim (_, be_eager, f) ->
          let args = List.map (eval_string_exp be_eager venv pos) args in
          let venv_new, result = venv_apply_prim_fun f venv_obj pos loc args in
Index: lib/Pervasives.om
===================================================================
--- lib/Pervasives.om	(revision 11539)
+++ lib/Pervasives.om	(working copy)
@@ -188,9 +188,10 @@
    object-map(f) =
       return $(obj-map $(this), $(f))
 
-   object-foreach(body, v, x) =
-      export
-      obj-map($(this), $(v), $(x), $(body))
+   object-foreach() =
+      f(body, v, x) =
+         export
+         obj-map($(this), $(v), $(x), $(body))
 
    instanceof(v) =
       return $(obj-instanceof $(this), $(v))
@@ -292,9 +293,11 @@
     map(f) =
         return $(map-map $(this), $(f))
 
-    foreach(body, v, x) =
-        export
-        map-map($(this), $(v), $(x), $(body))
+    foreach() =
+        private.This = $(this)
+        f(body, v, x) =
+            export
+            map-map($(private.This), $(v), $(x), $(body))
 
     length() =
         return $(map-length $(this))
@@ -429,9 +432,11 @@
    map(f) =
       sequence-map($(f), $(this))
 
-   foreach(body, v) =
-      export
-      sequence-map($(body), $(v), $(this))
+   foreach() =
+      private.This = $(this)
+      f(body, v) =
+         export
+         sequence-map($(body), $(v), $(private.This))
 
    forall(f) =
       sequence-forall($f, $(this))


More information about the OMake-Devel mailing list