zero-arity higher-order function terms and apply/1

Fergus Henderson fjh at murlibobo.cs.mu.OZ.AU
Thu Jul 24 01:19:46 AEST 1997


I wrote:

> | Allow zero-arity higher-order function terms.
> | 
> | compiler/typecheck.m:
> | 	Allow apply/1.
> | 
> | doc/reference_manual.texi:
> | 	Document that zero-arity higher-order function types, 
> | 	insts, modes, lambda expressions, and applications
> | 	are allowed.

I missed a few things first time around.  Here's a more complete version.

Allow zero-arity higher-order function terms.

compiler/typecheck.m:
compiler/modecheck_unify.m:
	Allow apply/1.

compiler/mercury_to_mercury.m:
	Fix the output of nullary higher-order function insts:
	previously it would output `(func() = Mode is Det)',
	but the correct output is `((func) = Mode is Det)'.

doc/reference_manual.texi:
	Document that zero-arity higher-order function
	types, insts, modes, lambda expressions, and applications
	are allowed.

tests/hard_coded/Mmake:
tests/hard_coded/nullary_ho_func.m:
tests/hard_coded/nullary_ho_func.exp:
tests/invalid/Mmake:
tests/invalid/nullary_ho_func_error.m:
tests/invalid/nullary_ho_func_error.err_exp:
	Test cases relating to the above change.

Index: typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/typecheck.m,v
retrieving revision 1.207
diff -u -r1.207 typecheck.m
--- typecheck.m	1997/06/29 23:11:36	1.207
+++ typecheck.m	1997/07/21 14:43:58
@@ -2174,7 +2174,7 @@
 builtin_apply_type(_TypeCheckInfo, Functor, Arity, ConsTypeInfos) :-
 	Functor = cons(unqualified(ApplyName), _),
 	( ApplyName = "apply" ; ApplyName = "" ),
-	Arity >= 2,
+	Arity >= 1,
 	Arity1 is Arity - 1,
 	higher_order_func_type(Arity1, TypeVarSet, FuncType, ArgTypes, RetType),
 	ConsTypeInfos = [cons_type_info(TypeVarSet, RetType,
@@ -3523,7 +3523,7 @@
 			[]
 		)
 	;
-		{ PredName = unqualified("apply"), Arity >= 2 }
+		{ PredName = unqualified("apply"), Arity >= 1 }
 	->
 		report_error_apply_instead_of_pred(TypeCheckInfo)
 	;
Index: modecheck_unify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.17
diff -u -r1.17 modecheck_unify.m
--- modecheck_unify.m	1997/07/02 08:06:17	1.17
+++ modecheck_unify.m	1997/07/23 14:49:57
@@ -119,7 +135,7 @@
 		HowToCheckGoal \= check_unique_modes,
 		ConsId0 = cons(unqualified(ApplyName), _),
 		( ApplyName = "apply" ; ApplyName = "" ),
-		Arity >= 2,
+		Arity >= 1,
 		ArgVars0 = [FuncVar | FuncArgVars]
 	->
 		%
Index: mercury_to_mercury.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.108
diff -u -r1.108 mercury_to_mercury.m
--- mercury_to_mercury.m	1997/06/29 23:11:01	1.108
+++ mercury_to_mercury.m	1997/07/23 15:01:02
@@ -453,9 +453,13 @@
 		;
 			{ PredOrFunc = function },
 			{ pred_args_to_func_args(Modes, ArgModes, RetMode) },
-			io__write_string("(func("),
-			mercury_output_mode_list(ArgModes, VarSet),
-			io__write_string(") = "),
+			( { Modes = [] } ->
+				io__write_string("((func) = ")
+			;
+				io__write_string("(func("),
+				mercury_output_mode_list(ArgModes, VarSet),
+				io__write_string(") = ")
+			),
 			mercury_output_mode(RetMode, VarSet),
 			io__write_string(" is "),
 			mercury_output_det(Det),

-----------------------------------------------------------------------------
tests/hard_coded/nullary_ho_func.m:
-----------------------------------------------------------------------------
% Test case for use of zero-arity higher-order function terms.
% 
% Author: fjh

:- module nullary_ho_func.
:- interface.
:- import_module io.

:- pred main(io__state::di, io__state::uo) is det.

:- implementation.
:- import_module std_util.

:- type nullary_func(T) == ((func) = T).
:- inst nullary_func == ((func) = out is det).

:- func apply_nullary_func(nullary_func(T)) = T.
:- mode apply_nullary_func(in(nullary_func)) = out is det.

apply_nullary_func(F) = apply(F).

:- func apply_func((func) = T) = T.
:- mode apply_func((func) = out is semidet) = out is semidet.
:- mode apply_func((func) = out is det) = out is det.

apply_func(F) = apply(F).

main -->
	{ F = ((func) = 42) },
	{ X = apply(F) },
	{ G = ((func) = (_ :: out) is semidet :- fail) },
	{ H = ((func) = (R :: out) is semidet :- semidet_succeed, R = X) },
	print("X = "), print(X), nl,
	print("apply(F) = "), print(X), nl,
	print("apply_func(F) = "), print(X), nl,
	print("apply_nullary_func(F) = "), print(X), nl,
	( { Y = apply(G) } ->
		print("Y = "), print(Y), nl
	;
		print("Y = apply(G) failed"), nl
	),
	( { Z = apply(H) } ->
		print("Z = "), print(Z), nl
	;
		print("Y = apply(G) failed"), nl
	).

-----------------------------------------------------------------------------
tests/valid/nullary_ho_func_error.m:
-----------------------------------------------------------------------------
% Test case for use of zero-arity higher-order function terms.
% 
% Author: fjh

:- module nullary_ho_func_error.
:- interface.
:- import_module io.

:- pred main(io__state::di, io__state::uo) is det.

:- implementation.

:- func pi = float.

pi = 3.14159.

main -->
	print("apply_nullary_func(pi) = "),
	% this would be legal:
	% print(apply_nullary_func((func) = pi)), nl.
	% this one is not:
	print(apply_nullary_func(pi)), nl.

:- func apply_nullary_func((func) = T) = T.
:- mode apply_nullary_func(in((func) = out is det)) = out is det.

apply_nullary_func(F) = apply(F).




More information about the developers mailing list