@@ -251,6 +251,8 @@ defmodule Module.Types.Apply do
251251 { Map , :pop , [ { [ open_map ( ) , term ( ) ] , tuple ( [ term ( ) , open_map ( ) ] ) } ] } ,
252252 { Map , :pop , [ { [ open_map ( ) , term ( ) , term ( ) ] , tuple ( [ term ( ) , open_map ( ) ] ) } ] } ,
253253 { Map , :pop! , [ { [ open_map ( ) , term ( ) ] , tuple ( [ term ( ) , open_map ( ) ] ) } ] } ,
254+ { Map , :replace , [ { [ open_map ( ) , term ( ) , term ( ) ] , open_map ( ) } ] } ,
255+ { Map , :replace_lazy , [ { [ open_map ( ) , term ( ) , fun ( 1 ) ] , open_map ( ) } ] } ,
254256 { Map , :update! , [ { [ open_map ( ) , term ( ) , fun ( 1 ) ] , open_map ( ) } ] } ,
255257 { :maps , :from_keys , [ { [ list ( term ( ) ) , term ( ) ] , open_map ( ) } ] } ,
256258 { :maps , :find ,
@@ -419,22 +421,22 @@ defmodule Module.Types.Apply do
419421 case map_update ( map , @ struct_key , not_set ( ) , false , true ) do
420422 { _value , descr , _errors } -> { :ok , return ( descr , args_types , stack ) }
421423 :badmap -> { :error , badremote ( Map , :from_struct , args_types ) }
422- { :error , _errors } -> { :error , { :badkeydomain , map , @ struct_key , nil } }
424+ { :error , _errors } -> { :error , { :badkeydomain , map , @ struct_key , "raise" } }
423425 end
424426 end
425427
426428 defp remote_apply ( Map , :get , _info , [ map , key ] = args_types , stack ) do
427429 case map_get ( map , key ) do
428430 { :ok , value } -> { :ok , return ( union ( value , @ nil_atom ) , args_types , stack ) }
429- :badmap -> { :error , badremote ( :maps , :get , args_types ) }
431+ :badmap -> { :error , badremote ( Map , :get , args_types ) }
430432 :error -> { :error , { :badkeydomain , map , key , @ nil_atom } }
431433 end
432434 end
433435
434436 defp remote_apply ( Map , :get , _info , [ map , key , default ] = args_types , stack ) do
435437 case map_get ( map , key ) do
436438 { :ok , value } -> { :ok , return ( union ( value , default ) , args_types , stack ) }
437- :badmap -> { :error , badremote ( :maps , :get , args_types ) }
439+ :badmap -> { :error , badremote ( Map , :get , args_types ) }
438440 :error -> { :error , { :badkeydomain , map , key , default } }
439441 end
440442 end
@@ -444,7 +446,7 @@ defmodule Module.Types.Apply do
444446 { :ok , default } ->
445447 case map_get ( map , key ) do
446448 { :ok , value } -> { :ok , return ( union ( value , default ) , args_types , stack ) }
447- :badmap -> { :error , badremote ( :maps , :get , args_types ) }
449+ :badmap -> { :error , badremote ( Map , :get_lazy , args_types ) }
448450 :error -> { :error , { :badkeydomain , map , key , default } }
449451 end
450452
@@ -477,36 +479,26 @@ defmodule Module.Types.Apply do
477479 case map_update ( map , key , not_set ( ) , true , false ) do
478480 { value , descr , _errors } -> { :ok , return ( tuple ( [ value , descr ] ) , args_types , stack ) }
479481 :badmap -> { :error , badremote ( Map , :pop! , args_types ) }
480- { :error , _errors } -> { :error , { :badkeydomain , map , key , nil } }
482+ { :error , _errors } -> { :error , { :badkeydomain , map , key , "raise" } }
481483 end
482484 end
483485
484- defp remote_apply ( Map , :update! , _info , [ map , key , fun ] = args_types , stack ) do
485- try do
486- { map , fun } =
487- case fun do
488- % { dynamic: fun } -> { dynamic ( map ) , fun }
489- _ -> { map , fun }
490- end
491-
492- fun_apply = fn arg_type ->
493- case fun_apply ( fun , [ arg_type ] ) do
494- { :ok , res } -> res
495- reason -> throw ( { :badapply , reason , [ arg_type ] } )
496- end
497- end
498-
499- map_update_fun ( map , key , fun_apply , false , false )
500- catch
501- { :badapply , reason , args_types } ->
502- { :error , { :badapply , fun , args_types , reason } }
503- else
486+ defp remote_apply ( Map , :replace , _info , [ map , key , value ] = args_types , stack ) do
487+ case map_update ( map , key , value , false , false ) do
504488 { _value , descr , _errors } -> { :ok , return ( descr , args_types , stack ) }
505- :badmap -> { :error , badremote ( Map , :update! , args_types ) }
506- { :error , _errors } -> { :error , { :badkeydomain , map , key , nil } }
489+ :badmap -> { :error , badremote ( Map , :replace , args_types ) }
490+ { :error , _errors } -> { :error , { :badkeydomain , map , key , "do nothing" } }
507491 end
508492 end
509493
494+ defp remote_apply ( Map , :replace_lazy , _info , args_types , stack ) do
495+ map_update_or_replace_lazy ( :replace_lazy , args_types , stack , "do nothing" )
496+ end
497+
498+ defp remote_apply ( Map , :update! , _info , args_types , stack ) do
499+ map_update_or_replace_lazy ( :update! , args_types , stack , "raise" )
500+ end
501+
510502 defp remote_apply ( :maps , :find , _info , [ key , map ] = args_types , stack ) do
511503 case map_get ( map , key ) do
512504 { _ , value } ->
@@ -559,7 +551,7 @@ defmodule Module.Types.Apply do
559551 case map_get ( map , key ) do
560552 { :ok , value } -> { :ok , return ( value , args_types , stack ) }
561553 :badmap -> { :error , badremote ( :maps , :get , args_types ) }
562- :error -> { :error , { :badkeydomain , map , key , nil } }
554+ :error -> { :error , { :badkeydomain , map , key , "raise" } }
563555 end
564556 end
565557
@@ -574,15 +566,15 @@ defmodule Module.Types.Apply do
574566 case map_update ( map , key , value , false , true ) do
575567 { _value , descr , _errors } -> { :ok , return ( descr , args_types , stack ) }
576568 :badmap -> { :error , badremote ( :maps , :put , args_types ) }
577- { :error , _errors } -> { :error , { :badkeydomain , map , key , nil } }
569+ { :error , _errors } -> { :error , { :badkeydomain , map , key , "raise" } }
578570 end
579571 end
580572
581573 defp remote_apply ( :maps , :remove , _info , [ key , map ] = args_types , stack ) do
582574 case map_update ( map , key , not_set ( ) , false , true ) do
583575 { _value , descr , _errors } -> { :ok , return ( descr , args_types , stack ) }
584576 :badmap -> { :error , badremote ( :maps , :remove , args_types ) }
585- { :error , _errors } -> { :error , { :badkeydomain , map , key , nil } }
577+ { :error , _errors } -> { :error , { :badkeydomain , map , key , "raise" } }
586578 end
587579 end
588580
@@ -611,7 +603,7 @@ defmodule Module.Types.Apply do
611603 case map_update ( map , key , value , false , false ) do
612604 { _value , descr , _errors } -> { :ok , return ( descr , args_types , stack ) }
613605 :badmap -> { :error , badremote ( :maps , :update , args_types ) }
614- { :error , _errors } -> { :error , { :badkeydomain , map , key , nil } }
606+ { :error , _errors } -> { :error , { :badkeydomain , map , key , "raise" } }
615607 end
616608 end
617609
@@ -975,6 +967,34 @@ defmodule Module.Types.Apply do
975967 end
976968 end
977969
970+ ## Map helpers
971+
972+ def map_update_or_replace_lazy ( name , [ map , key , fun ] = args_types , stack , error ) do
973+ try do
974+ { map , fun } =
975+ case fun do
976+ % { dynamic: fun } -> { dynamic ( map ) , fun }
977+ _ -> { map , fun }
978+ end
979+
980+ fun_apply = fn arg_type ->
981+ case fun_apply ( fun , [ arg_type ] ) do
982+ { :ok , res } -> res
983+ reason -> throw ( { :badapply , reason , [ arg_type ] } )
984+ end
985+ end
986+
987+ map_update_fun ( map , key , fun_apply , false , false )
988+ catch
989+ { :badapply , reason , args_types } ->
990+ { :error , { :badapply , fun , args_types , reason } }
991+ else
992+ { _value , descr , _errors } -> { :ok , return ( descr , args_types , stack ) }
993+ :badmap -> { :error , badremote ( Map , name , args_types ) }
994+ { :error , _errors } -> { :error , { :badkeydomain , map , key , error } }
995+ end
996+ end
997+
978998 ## Application helpers
979999
9801000 defp return ( type , args_types , stack ) do
@@ -1257,10 +1277,10 @@ defmodule Module.Types.Apply do
12571277
12581278 #{ to_quoted_string ( key ) |> indent ( 4 ) }
12591279
1260- therefore this function will always #{ if error do
1261- "return #{ to_quoted_string ( error ) } "
1280+ therefore this function will always #{ if is_binary ( error ) do
1281+ error
12621282 else
1263- "raise "
1283+ "return #{ to_quoted_string ( error ) } "
12641284 end }
12651285 """ ,
12661286 format_traces ( traces )
0 commit comments