Closed unthingable closed 6 months ago
Fixed in https://github.com/LogtalkDotOrg/logtalk3/commit/3b417b243fadb3abb7d36a4ce72431091d4c8a09:
$ cat te.pl
term_expansion(ab, [
(:- object(a)),
(:- public(x/1)),
x(1),
(:- end_object),
(:- object(b)),
(:- public(y/1)),
y(1),
(:- end_object)
]).
$ cat ab.lgt
ab.
$ swilgt -q
?- [te].
true.
?- logtalk_load(ab, [hook(user)]).
true.
?- a::x(X).
X = 1.
?- b::y(Y).
Y = 1.
Can you tell me your first and last name so that I can credit the bug report? Fine if you prefer to remain anonymous.
Thank you!
FWIW, this is what I needed it for:
:- object(opt, imports(options)).
:- end_object.
:- protocol(defaultp).
:- public(default/1).
:- mode(default(-term), one).
:- end_protocol.
:- object(types_util).
:- public(replace_nth_arg/4).
replace_nth_arg(N, NewArg, Pred0, Pred) :-
Pred0 =.. [P|List],
list::nth1(N, List, _, TempList),
list::nth1(N, NewList, NewArg, TempList),
Pred =.. [P|NewList].
:- end_object.
:- object(types_hook, implements(expanding)).
accessor(Name, Num, Obj) :-
atom_concat(Name, '_set', SetterName),
atom_concat(Name, '_get', GetterName),
Getter0 =.. [Name, X],
Getter =.. [GetterName, X],
Setter =.. [SetterName, Val, Pred],
Obj = [
(:- public(Name/1)),
(Getter0 :- parameter(Num, X)),
(:- public(GetterName/1)),
(Getter :- parameter(Num, X)),
(:- public(SetterName/2)),
(
Setter :- this(Pred0),
types_util::replace_nth_arg(Num, Val, Pred0, Pred)
)
].
term_expansion(type(X), Obj) :-
term_expansion(type(X, []), Obj).
term_expansion(type(X, Options), Obj) :-
X =.. [Atom|Args],
length(Args, Length),
{numlist(1, Length, Numbers)},
length(Vars, Length),
Odecl =.. [Atom|Vars],
meta::map(accessor, Args, Numbers, Accessors0),
list::append(Accessors0, Accessors),
( opt::option(default(Def), Options)
-> Companion = [
(:- object(Atom, implements(defaultp))),
default(Def),
(:- end_object)
],
Head = object(Odecl, extends(Atom)),
DefPred = [default(Def)]
; Companion = [],
Head = object(Odecl),
DefPred = []
),
list::append([
Companion,
[(:- Head)],
Accessors,
DefPred,
[(:- end_object)]
], Obj).
:- end_object.
It's the record I always wanted in Prolog (with a Scala case class smell).
type(
foo(a,b),
[default(foo(1,2))]
).
?- foo(3,4)::b(X).
X = 4.
?- foo(3,4)::b_set(999, X), X::b(Y).
X = foo(3, 999),
Y = 999.
?- foo(_,_)::default(X).
X = foo(1, 2).
?- foo::default(X).
X = foo(1, 2).
The companion object simplifies access to "static" methods.
Perhaps there is a better and easier way to do this, I'm quite new to Logtalk.
Nice use of the term-expansion mechanism.
When working with parametric objects, you can always derive from them other objects that fix some of the parameters. For example:
:- object(foo(_X_, _Y_)).
:- public(x/1).
x(_X_).
:- public(y/1).
y(_Y_).
...
:- end_object.
:- object(foo, extends(foo(1,2))).
:- end_object.
P.S. You can use integer::sequence/3
instead of the backend numlist/3
. There's also list::length/2
for portability.
Excellent suggestions, thanks!
Since we're on this topic, a couple of unrelated questions.
foo(1,2)
from the object foo
?A::a_get(B), B::b_set(X, C), C::c_get(D)
one could write A:>a_get:>b_set(X):>c_get(D)
(using an imaginary operator :>
that chains members on the last argument of previous one).Pretty sure I can define a naive version of one, just wanted to make sure one doesn't already exist. That would make an almost complete lens.
What would you say about this approach?
For (1), a solution could be:
:- object(foo(_X_, _Y_)).
:- public(x/1).
x(_X_).
:- public(y/1).
y(_Y_).
:- public(default/1).
default(This) :-
this(This).
...
:- end_object.
:- object(foo, extends(foo(1,2))).
:- end_object.
?- foo::default(D).
D = foo(1, 2).
For (2), there's currently no chaining operator. I suggest you look into DCGs.
Closing as the original bug reported is fixed.
Not sure if I'm misusing it, but seems like this should be possible.
When loading a file with
ab.
term using this hook:From limited poking around it appears to react poorly specifically to predicates declared in the second object. For example, this works fine:
Logtalk 3.78.0 SWI-Prolog (threaded, 64 bits, version 9.3.2-10-gf146a507d)