Re: A couple of questions about goops method parameters

2014-09-07 Thread Neil Jerram
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com writes:

 Panicz Maciej Godek godek.mac...@gmail.com writes:

 [...] it's hard for me to see the advantage of FRP over OOP in
 practical systems (e.g. windowed applications with buttons and so
 on). [...]

 An off-topic remark:

 I don't know about *functional* reactive programming but from my
 experience so far as an iOS developer, I've been *longing* for a
 reactive programming system that automates state changes even if not
 fully hiding them.  It would be invaluable being able to say
 button2.leftEdge = button1.rightEdge + 20px and have this equation be
 held automatically on changes to the layout of button1 (which might
 happen because it itself reacts to other layout changes), or to be able
 to say button.disabled = condition1 or condition2 and have the
 disabled status of button update automatically as the truthiness of the
 conditions changes.  (The former use-case is actually covered by layout
 constraints, but that's strictly limited to layouting.)

IIRC, Metafont does that; but obviously it isn't intended as a general
language.  Are there more general languages that solve equations like
this?

Regards,
Neil



Re: A couple of questions about goops method parameters

2014-09-07 Thread Taylan Ulrich Bayirli/Kammer
Neil Jerram n...@ossau.homelinux.net writes:

 IIRC, Metafont does that; but obviously it isn't intended as a general
 language.  Are there more general languages that solve equations like
 this?

From what I know, Prolog.

Other than that, Scheme. ;)

Apart from David's FRP implementation, I worked on the following a
little:

https://gitorious.org/taylan-guile/reactive/

(Warning: I might force-push commits to that repo at times.  It's not
ready for consumption.)

I don't consider it complete, and it might be broken.  Some simple
examples work:

guile ,use (reactive base)
guile (define x 0)
guile (define v (make-value () x))
guile (define v2 (make-value (v) (display recalculated\n) (+ v 5)))
guile (get/tainted v2)
recalculated
$2 = 5
guile (get/tainted v2)
$3 = 5
guile (set! x 1)
guile (taint! v)
guile (get/tainted v2)
recalculated
$4 = 6
guile

As you see, it's not purely-functional, and it requires explicit
tainting of root values.  After that, though, requesting any value
which directly or indirectly depends on that root will ignite a
recalculation of the graph of dependent values up to the requested one.

I continuously get confused while trying to reason about the precise
behavior of this system (even though it's very small), and had grave
bugs in it at times (actually I just fixed one while writing this
because I did a wholesale clean-up on the repo and re-uploaded it at the
above link).  Therefore, please don't trust that module for real
usage.

Taylan



Re: A couple of questions about goops method parameters

2014-09-07 Thread Taylan Ulrich Bayirli/Kammer
Marko Rauhamaa ma...@pacujo.net writes:

 It's perfectly fine to avoid errors by generalizing semantics so I
 wouldn't mind if you did what you propose. However, the dynamic type
 system is necessary for the simple fact that you will need to define
 runtime semantics.

Oh, I was rather looking at things from a low-level perspective.  E.g.
the foo string in my example was meant as a pointer, whose numeric
value plus 5 resulted in an integer whose underlying byte sequence is
then interpreted as an IEEE double.

In other words I was suggesting that by default there are only byte
sequences, and type systems help to work with these conveniently.

 No, the primary objective is not to prevent errors but to have
 well-defined semantics. Scheme, Python, C or Java would function
 perfectly well without any type error checking, static or dynamic. The
 results could be undefined or a burning computer, that doesn't matter.
 What matters is that you know what a well-defined program is supposed
 to do.

I think I understand your viewpoint, and it also makes sense: types
might not be essential to bit-crunching, but they are to abstract models
of computation.

 However, in my extensive practical experience, a static type system,

  [...]

Does that experience cover languages like SML, Ocaml, and Haskell?  (Not
a rhetorical question, though I suspect it doesn't; at least not as much
as languages like C, C++, and Java.)

Taylan



Re: A couple of questions about goops method parameters

2014-09-07 Thread Marko Rauhamaa
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com:

 Marko Rauhamaa ma...@pacujo.net writes:
 However, in my extensive practical experience, a static type system,

  [...]

 Does that experience cover languages like SML, Ocaml, and Haskell?

I have had superficial experience with SML way back (late 80's). No idea
how the languages would work in practice. However, I don't feel I'm
missing anything in Scheme.

 (Not a rhetorical question, though I suspect it doesn't; at least not
 as much as languages like C, C++, and Java.)

Not anywhere near as much. What do you have to say about those
languages?


Marko



Re: A couple of questions about goops method parameters

2014-09-07 Thread Taylan Ulrich Bayirli/Kammer
Marko Rauhamaa ma...@pacujo.net writes:

 Not anywhere near as much. What do you have to say about those
 languages?

Just what I said previously: many users of languages with more
sophisticated static type systems like Ocaml or Haskell say they prefer
that over dynamic typing.  I don't have much experience myself, though
at times I also felt positive about the ability to encode some logic in
a static type system.

Taylan



Re: A couple of questions about goops method parameters

2014-09-06 Thread Panicz Maciej Godek
2014-09-06 0:14 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:

  * [GOOPS] introduces a very strong, almost Linnaean, type system to
Scheme, where it seems out of place. I see no principal reason for
such classification. I don't declare my numbers in Scheme; why
should I declare my object types?

 I don't think I understand. There is no strong type system, and
 there's no need to declare object types. The types are mainly for
 convinience -- to allow you to implement the same interfaces for
 different objects.

 The types are a great inconvenience, syntactically and conceptually.
 Syntactically, your GOOPS method de, it plainly extends the means of 
 expression (and I think there's no problem in providing one's own syntax with 
 a macro)finitions make your Scheme code look
 like Pascal with the class names sprinkled among the parameters.
 Conceptually, the classes force me to put objects into buckets that
 don't correspond to my thought processes. Even Java offers anonymous
 classes for the purpose.

Now I don't understand what you're saying to even bigger extent.
GOOPS does not offer a type system, but a multiple method dispatch
system. It doesn't take away any freedom of using GOOPS objects with
regular Scheme functions, but allows to use one interface for
different implementations. Whether one likes the syntax or not, it
plainly extends the means of expression (and I think there's no
problem in providing one's own syntax with a macro)

However, I'd rather say that the lack of any type system in Guile is
an inconvinience, because static type checking allows to avoid a huge
class of software errors, and a good type system (like the one in
Haskell) actually enhances language's expressiveness. It's an issue
that's been talked over so many times, that it's already present in
comic strips:
http://ro-che.info/ccc/17



Re: A couple of questions about goops method parameters

2014-09-06 Thread Taylan Ulrich Bayirli/Kammer
Panicz Maciej Godek godek.mac...@gmail.com writes:

 However, I'd rather say that the lack of any type system in Guile is
 an inconvinience, because static type checking allows to avoid a huge
 class of software errors, and a good type system (like the one in
 Haskell) actually enhances language's expressiveness. It's an issue
 that's been talked over so many times, that it's already present in
 comic strips:
 http://ro-che.info/ccc/17

I suspect that comic strip comes from someone who mostly witnessed silly
flamewars between Haskellites with a higher-than-thou attitude, and CS
unwary users of languages like JavaScript, Python, Ruby, etc. ;)

In fact, the whole mention of a battle between the two groups, and
showing zero overlap between the proponents of either strategy, tells
me that the author is seriously misguided themselves.  Maybe I'm reading
too much into it, but what's at least obvious is that the author is a
fan of Haskell.

I'm sure that most serious Lispers and other CS-aware dynlang users are
aware of the expressive power of good static type systems, and have
respect for ML and Miranda descendants.  However, I don't know of any
hard evidence for the relevancy of the class of bugs prevented by static
typing, given there is otherwise good program design and documentation.
Only recently I met a static typing proponent who was merely spiteful
against the horrible practices of some web developers (JavaScript users)
they worked with...

A good optional static type system could be neat for Guile, but not sure
what priority this should have.  (For now I would rather want sealed
modules and the ability to static-import them into another.)

Taylan



Re: A couple of questions about goops method parameters

2014-09-06 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 However, I'd rather say that the lack of any type system in Guile is
 an inconvinience, because static type checking allows to avoid a huge
 class of software errors, and a good type system (like the one in
 Haskell) actually enhances language's expressiveness.

We already have a satisfactory selection of languages with static type
annotation. The primary upside of static types is much faster code. The
downside is boilerplate and clutter that make it a huge chore to write
and maintain the code. In my experience, high-level programming
languages allow you to accomplish more challenging feats with better
quality and productivity than statically typed languages.

I'm saying use low-level programming languages when you have to and
high-level programming languages when you can.


Marko



Re: A couple of questions about goops method parameters

2014-09-06 Thread Taylan Ulrich Bayirli/Kammer
Marko Rauhamaa ma...@pacujo.net writes:

 The primary upside of static types is much faster code.

Optimization of dynamic typing can go pretty far AFAIK.  In an ideal
case, type-checks are hoisted to outside critical sections of code and
don't affect the speed of e.g. a tight loop.  And then there's JIT and
all that jazz...

 The downside is boilerplate and clutter that make it a huge chore to
 write and maintain the code.

Users of languages with good static type systems like ML and Miranda
descendants would rather argue that types make the program more
maintainable, and aren't too much of a bother since they're inferred in
many common cases.  Not my own experience, but I have no reason for a
wholesale disbelief against them (only skepticism on *how* great static
typing is).

 In my experience, high-level programming languages allow you to
 accomplish more challenging feats with better quality and productivity
 than statically typed languages.

 I'm saying use low-level programming languages when you have to and
 high-level programming languages when you can.

Using high-level/dynamically-typed, and low-level/statically-typed as
synonyms seems pretty wrong.  There are very low-level dynamically typed
languages (Forth), and very high-level statically typed ones (Haskell).

Taylan



Re: A couple of questions about goops method parameters

2014-09-06 Thread Nala Ginrut
2014年9月6日 上午4:10于 Panicz Maciej Godek godek.mac...@gmail.com写道:

 dthomps...@worcester.edu:
  http://elm-lang.org/learn/What-is-FRP.elm
 
  Using FRP, we can model with mutable state in a pure, functional way.

 OTOH, when you take a look at the example code (Mario), you can trace
 the notion of objects. E.g.
 mario = { x = 0, y = 0, vx = 0, vy = 0, dir = right }

 What else is that, if not an object?
 Well, it's a structure, one could say -- because it has no methods.
 However, this is just what the most rudimentary GOOPS objects are -- a
 named tuple (provided that you use no virtual slots). I think that it
 is a big problem of Scheme, that it does not have any noncontroversial
 and commonly accepted way for creating named tuples.


Doesn't assoc-list fill the gap?

 Furthermore, instead of using explicit side effects, as one would
 normally do, the Mario example first defines a step function, and
 calls foldp step mario input. Although I do appreciate efforts like
 in How to Design Worlds book or Introduction to Systematic Program
 Design course, to avoid explicit mutation (because as SICP shows, it
 complicates the model of computation), I don't see so many benefits of
 avoiding mutation in complex realtime systems.


I partly agree with you. For stateless makes things complex. Yes, it could
be complex.
But, no, it depends on need and scenario. The advantage of stateless is to
provide a more reliable and understandable system to users and maintainers.
If your system is constrained by hard  realtime need, go ahead with
side-effect, it's cool. But most of the time, it's not the story from
reasonable users.
If you doubt stateless party exaggerated the truth, I'll recommend this
paper: Out of the tar pit

 Actually, when I look at the Mario example, I have a feeling that the
 code would be much cleaner and easier to follow if it was written in a
 more traditional imperative/callback style.

It's fine if you think imperative is still cool in FP, me too, since most
people living in non-FP land.
But if you're expecting imperative way in FP land rather than learning and
trying it in FP way, why not choose non-FP lang for it? :-)


Re: A couple of questions about goops method parameters

2014-09-06 Thread Panicz Maciej Godek
2014-09-06 13:27 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:
 Panicz Maciej Godek godek.mac...@gmail.com:

 However, I'd rather say that the lack of any type system in Guile is
 an inconvinience, because static type checking allows to avoid a huge
 class of software errors, and a good type system (like the one in
 Haskell) actually enhances language's expressiveness.

 We already have a satisfactory selection of languages with static type
 annotation. The primary upside of static types is much faster code. The
 downside is boilerplate and clutter that make it a huge chore to write
 and maintain the code.

Taylan already wrote a few remarks on that statement. Obviously, when
you're talking about statically typed languages, you mean C, Pascal,
and its derivatives. However, you're mistaken. Haskell or ML are also
statically typed, but because of type inference, they do not introduce
any boilerplate nor clutter.

The fact that C compiler performs static type checking has nothing to
do with its performance. It's only about detecting type errors. So for
example if you have code like:

short f();

long g() {
  return f();
}

the compiler will generate an error. An alternative would be to
compile according to specification and let the user worry about the
problems caused by type mismatch (and I think that this is what the
early C compilers were doing)

 In my experience, high-level programming
 languages allow you to accomplish more challenging feats with better
 quality and productivity than statically typed languages.

In addition to Taylan's remark, my experience is that in large
programs it's very easy to make a type error, and it may take some
time for that bug to manifest, and because of that latency such bugs
become more confusing and harder to trace. Furthermore, having type
signatures often make complex programs easier to read.



Re: A couple of questions about goops method parameters

2014-09-06 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 The fact that C compiler performs static type checking has nothing to
 do with its performance. It's only about detecting type errors. So for
 example if you have code like:

 short f();

 long g() {
   return f();
 }

 the compiler will generate an error.

(It actually doesn't. Try it.)

You are right that C compilation would simply not be possible without
static type information present. However, since Scheme can do everything
C can without static type information, the principal justification for
its existence is performance. That's why Guido van Rossum is tempted to
add optional static type annotation to Python: it would make it possible
replace Java/C# with Python.


Marko



Re: A couple of questions about goops method parameters

2014-09-05 Thread Carlos Pita
Hi Nala,

 IMO, when you have lambda*, you never need define-method. Actually, I
 want to say, once you have such FP features, you don't need OOP
 anymore.

I really don't see classes and multimethods a la CLOS competing against
FP features. They are about certain ways of composing structures and
providing common functional interfaces to them (and so, about certain
ways of dispatching function calls). They don't promote mutability. They
don't promote packaging data and methods in rigid ways. They just
capture a pattern that would be cumbersome to implement by hand each
time (even with the help of metaprogramming).

I don't care about everything is an object stuff, but I do care about
using the right tool for the problem at hand, and it feels good when the
problem is a frequent one and the tool already exists.

 You can mix them while programming, but you don't have to.  Anyway, if
you try to avoid to use GOOPS someday, you have to handle dispatching
by yourself. ;-)

You see. There could be cases for which goops dispatching were not good
enough, I can't say it for sure. But multimethods are an incredible
flexible mechanism and you still have the mop to tweak, so I will write
my own dispatching code and meta-code only as a last LAST resource.

Best regards
--
Carlos




Re: A couple of questions about goops method parameters

2014-09-05 Thread Panicz Maciej Godek
2014-09-05 10:32 GMT+02:00 Nala Ginrut nalagin...@gmail.com:
 Hi Carlos!

 On Tue, 2014-09-02 at 23:05 -0300, Carlos Pita wrote:

 2) What is the relationship between the lambda* family and methods?
 Are methods restricted in the sense that they can't aspire to get the
 greater flexibility of lambda* parameter handling? Maybe because of
 the way dispatching is done?


 IMO, when you have lambda*, you never need define-method. Actually, I
 want to say, once you have such FP features, you don't need OOP anymore.

So perhaps you could tell me how to design a GUI framework in FP and
without OOP. To me it seems that GUI is the main domain the OOP was
crafted for, but if you have some nice functional ideas, perhaps you
could help me to redesign my framework.

The base of the framework can be browsed here:

https://bitbucket.org/panicz/slayer/src/94c9dde264759cbbd8d4a88d2581b77f55cc0bd6/guile-modules/widgets/base.scm?at=default

What is particularly relevant is the widget class. I recently
started creating my own OOP framework atop of GOOPS, so the same class
could be equivalently written as

https://bitbucket.org/panicz/slayer/src/94c9dde264759cbbd8d4a88d2581b77f55cc0bd6/guile-modules/extra/noobs.scm?at=default
(see at the bottom)

But I don't see any good alternative to OOP.



Re: A couple of questions about goops method parameters

2014-09-05 Thread David Thompson
Panicz Maciej Godek godek.mac...@gmail.com writes:

 So perhaps you could tell me how to design a GUI framework in FP and
 without OOP. To me it seems that GUI is the main domain the OOP was
 crafted for, but if you have some nice functional ideas, perhaps you
 could help me to redesign my framework.


Are you familiar with functional reactive programming?

http://elm-lang.org/learn/What-is-FRP.elm

Using FRP, we can model with mutable state in a pure, functional way.
That is, the necessary mutation is hidden behind the runtime of the FRP
implementation.

Just some food for thought.

-- 
David Thompson
Web Developer - Free Software Foundation - http://fsf.org
GPG Key: 0FF1D807
Support the FSF: https://fsf.org/donate



Re: A couple of questions about goops method parameters

2014-09-05 Thread Panicz Maciej Godek
2014-09-05 21:12 GMT+02:00 David Thompson dthomps...@worcester.edu:
 Panicz Maciej Godek godek.mac...@gmail.com writes:

 So perhaps you could tell me how to design a GUI framework in FP and
 without OOP. To me it seems that GUI is the main domain the OOP was
 crafted for, but if you have some nice functional ideas, perhaps you
 could help me to redesign my framework.


 Are you familiar with functional reactive programming?

 http://elm-lang.org/learn/What-is-FRP.elm

 Using FRP, we can model with mutable state in a pure, functional way.
 That is, the necessary mutation is hidden behind the runtime of the FRP
 implementation.

 Just some food for thought.

Sure, I've been reading a lot, but I didn't manage to get much of it.
I mean, the toy examples are really nice, but it's hard for me to see
the advantage of FRP over OOP in practical systems (e.g. windowed
applications with buttons and so on). Although I see value in
encapsulating state mutations, the notion of state seems inevitable in
describing such applications (like the mere fact that a checkbox can
be checked or not -- so it's a state which is a part of the
description).

BTW I recently ran into a problem with your signal propagation
framework from (guile 2d). Namely, if a signal is itself a mutable
object (like a vector or an array), then changing the value of that
object doesn't propagate (because it happens only when you use
slot-set!, and not (vector-set! (slot-ref ...)...)).
I can't find any workaround for that.



Re: A couple of questions about goops method parameters

2014-09-05 Thread David Thompson
Panicz Maciej Godek godek.mac...@gmail.com writes:

 2014-09-05 21:12 GMT+02:00 David Thompson dthomps...@worcester.edu:
 Panicz Maciej Godek godek.mac...@gmail.com writes:

 So perhaps you could tell me how to design a GUI framework in FP and
 without OOP. To me it seems that GUI is the main domain the OOP was
 crafted for, but if you have some nice functional ideas, perhaps you
 could help me to redesign my framework.


 Are you familiar with functional reactive programming?

 http://elm-lang.org/learn/What-is-FRP.elm

 Using FRP, we can model with mutable state in a pure, functional way.
 That is, the necessary mutation is hidden behind the runtime of the FRP
 implementation.

 Just some food for thought.

 Sure, I've been reading a lot, but I didn't manage to get much of it.
 I mean, the toy examples are really nice, but it's hard for me to see
 the advantage of FRP over OOP in practical systems (e.g. windowed
 applications with buttons and so on). Although I see value in
 encapsulating state mutations, the notion of state seems inevitable in
 describing such applications (like the mere fact that a checkbox can
 be checked or not -- so it's a state which is a part of the
 description).


Yes, it's state, and state will always be there in a realtime
application.  However, you can still model it in a functional way with
procedures that are idempotent and objects that are immutable.  You just
need to glue it all together with something that tracks the current
state of the application.

 BTW I recently ran into a problem with your signal propagation
 framework from (guile 2d). Namely, if a signal is itself a mutable
 object (like a vector or an array), then changing the value of that
 object doesn't propagate (because it happens only when you use
 slot-set!, and not (vector-set! (slot-ref ...)...)).
 I can't find any workaround for that.

I don't consider it a problem because the values stored signals are
intended to be immutable.  I will make that clear when I get around to
documenting things better.  If you mutate an object within the signal
graph, bad things are bound to happen.  The only reasonable side-effects
are those that do not change values stored within signals, like writing
to a log file or playing a sound.  I have intentionally kept mutation at
lowest layer of the system, abstracted away from the user.

-- 
David Thompson
Web Developer - Free Software Foundation - http://fsf.org
GPG Key: 0FF1D807
Support the FSF: https://fsf.org/donate



Re: A couple of questions about goops method parameters

2014-09-05 Thread Panicz Maciej Godek
dthomps...@worcester.edu:
 http://elm-lang.org/learn/What-is-FRP.elm

 Using FRP, we can model with mutable state in a pure, functional way.

OTOH, when you take a look at the example code (Mario), you can trace
the notion of objects. E.g.
mario = { x = 0, y = 0, vx = 0, vy = 0, dir = right }

What else is that, if not an object?
Well, it's a structure, one could say -- because it has no methods.
However, this is just what the most rudimentary GOOPS objects are -- a
named tuple (provided that you use no virtual slots). I think that it
is a big problem of Scheme, that it does not have any noncontroversial
and commonly accepted way for creating named tuples.

Furthermore, instead of using explicit side effects, as one would
normally do, the Mario example first defines a step function, and
calls foldp step mario input. Although I do appreciate efforts like
in How to Design Worlds book or Introduction to Systematic Program
Design course, to avoid explicit mutation (because as SICP shows, it
complicates the model of computation), I don't see so many benefits of
avoiding mutation in complex realtime systems.

Actually, when I look at the Mario example, I have a feeling that the
code would be much cleaner and easier to follow if it was written in a
more traditional imperative/callback style.



Re: A couple of questions about goops method parameters

2014-09-05 Thread Taylan Ulrich Bayirli/Kammer
Panicz Maciej Godek godek.mac...@gmail.com writes:

 [...] it's hard for me to see the advantage of FRP over OOP in
 practical systems (e.g. windowed applications with buttons and so
 on). [...]

An off-topic remark:

I don't know about *functional* reactive programming but from my
experience so far as an iOS developer, I've been *longing* for a
reactive programming system that automates state changes even if not
fully hiding them.  It would be invaluable being able to say
button2.leftEdge = button1.rightEdge + 20px and have this equation be
held automatically on changes to the layout of button1 (which might
happen because it itself reacts to other layout changes), or to be able
to say button.disabled = condition1 or condition2 and have the
disabled status of button update automatically as the truthiness of the
conditions changes.  (The former use-case is actually covered by layout
constraints, but that's strictly limited to layouting.)

Declarative programming FTW.

Taylan



Re: A couple of questions about goops method parameters

2014-09-05 Thread Panicz Maciej Godek
2014-09-05 22:18 GMT+02:00 Taylan Ulrich Bayirli/Kammer
taylanbayi...@gmail.com:
 Panicz Maciej Godek godek.mac...@gmail.com writes:

 [...] I think that it is a big problem of Scheme, that it does not
 have any noncontroversial and commonly accepted way for creating named
 tuples.

 Does SRFI-9 not count because it creates tuple *types* and doesn't
 support immediate creation of tuples of an anonymous type?  (Could be
 an interesting feature, though not sure how useful in the end.)  Or do
 you just not consider SRFI-9 to be commonly accepted?  AFAIK it's pretty
 widely implemented, and for the record(!) it's been standardized as a
 part of R7RS-small.

There are a few issues here. The fact that it is impossible to create
anonymous type is one thing. Another is that each record type
introduces accessor bindings to a global namespace. In case of Elm,
one could write
mario = { x = 0, y = 0, dx = 0, dy = 0 }
and then access the fields with the dot notation, i.e. mario.x

There are other representations (like basket list or assoc list) that
avoid that problem, but they generate other ones -- namely, that the
access times get linear, and in case of assoc lists there is a huge
overhead of data, and in case of basket lists one needs to pass around
additional information regarding the names of subsequent fields.

And the sole fact that there are other reasonable represetations leads
to the conclusion that none is commonly accepted.

(Actually I think the nicest solution I've seen was in Erlang, but
unfortunately it wouldn't go well with Scheme)



Re: A couple of questions about goops method parameters

2014-09-05 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 I think that it is a big problem of Scheme, that it does not have any
 noncontroversial and commonly accepted way for creating named tuples.

That's what alists are. They may not be the most beautiful way to
represent data as S expressions but they sure are noncontroversial and
commonly accepted.

However, objects, in my opinion, are the antithesis of tuples. Objects
are the focal points of methods. Whether the black box contains data and
in what form is none of the rest of the world's concern.

IMO, GOOPS has two main flaws:

 * It brings an object's data slots to the fore while brushing methods
   aside. The object constructor syntax is more or less directly tied to
   the data slots.

 * It introduces a very strong, almost Linnaean, type system to Scheme,
   where it seems out of place. I see no principal reason for such
   classification. I don't declare my numbers in Scheme; why should I
   declare my object types?


Marko



Re: A couple of questions about goops method parameters

2014-09-05 Thread David Thompson
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com writes:

 Panicz Maciej Godek godek.mac...@gmail.com writes:

 [...] it's hard for me to see the advantage of FRP over OOP in
 practical systems (e.g. windowed applications with buttons and so
 on). [...]

 An off-topic remark:

 I don't know about *functional* reactive programming but from my
 experience so far as an iOS developer, I've been *longing* for a
 reactive programming system that automates state changes even if not
 fully hiding them.  It would be invaluable being able to say
 button2.leftEdge = button1.rightEdge + 20px and have this equation be
 held automatically on changes to the layout of button1 (which might
 happen because it itself reacts to other layout changes), or to be able
 to say button.disabled = condition1 or condition2 and have the
 disabled status of button update automatically as the truthiness of the
 conditions changes.  (The former use-case is actually covered by layout
 constraints, but that's strictly limited to layouting.)


In my reactive programming system, you could say:

  (define-signal button2-left-edge
(signal-map (cut +  20) button1-right-edge))

Which is, of course, more verbose than your example.  I want to explore
creating a macro that would abstract away the unboxing of signals so I
could simply write...

  (define-signal button-2-left-edge
(+ button1-right-edge 20))

... and it would DTRT.  Racket's FrTime can do this, which is neat.

 Declarative programming FTW.


Agreed. :)

-- 
David Thompson
Web Developer - Free Software Foundation - http://fsf.org
GPG Key: 0FF1D807
Support the FSF: https://fsf.org/donate



Re: A couple of questions about goops method parameters

2014-09-05 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 There are other representations (like basket list or assoc list) that
 avoid that problem, but they generate other ones -- namely, that the
 access times get linear, and in case of assoc lists there is a huge
 overhead of data, and in case of basket lists one needs to pass around
 additional information regarding the names of subsequent fields.

Dynamic programming languages lack a true, efficient dot notation.
That's a price I'm willing to pay (especially since Guile allows me to
switch to C where necessary). For example, Python and JavaScript
translate x.f into a hash table lookup.

In my tests, Guile's alists are more efficient than hash tables up to
maybe a hundred elements or so (IIRC). That's why I switched to alists
in my tiny object system.

As for the data overhead, I haven't yet really run into that problem.
Again, high memory use is a common issue with dynamic programming
languages. Python's objects are quite sizable as well.


Marko



Re: A couple of questions about goops method parameters

2014-09-05 Thread Panicz Maciej Godek
2014-09-05 22:44 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:
 Panicz Maciej Godek godek.mac...@gmail.com:

 I think that it is a big problem of Scheme, that it does not have any
 noncontroversial and commonly accepted way for creating named tuples.

 That's what alists are. They may not be the most beautiful way to
 represent data as S expressions but they sure are noncontroversial and
 commonly accepted.

I think that (putting side other issues) if one person in this thread
claims that srfi-9 is a commonly accepted representation, and another
claims that alists are a a commonly accepted representation, then it's
a proof that none is commonly accepted.

 However, objects, in my opinion, are the antithesis of tuples. Objects
 are the focal points of methods. Whether the black box contains data and
 in what form is none of the rest of the world's concern.

Apparently our views on the essence of OOP differ. I perceive an
object as an aggregation of properties, and a set of methods I would
call an interface. Perhaps to you doing OOP is about defining
interfaces, and to me it's more about aggregating properties. I
wouldn't say that anyone of us is more right than the other.

 IMO, GOOPS has two main flaws:

  * It brings an object's data slots to the fore while brushing methods
aside. The object constructor syntax is more or less directly tied to
the data slots.

I agree that the constructor syntax isn't expressible to handle some
very common use cases, and requires to overload the initialize
method in many trivial situations. But my solution to this problem is
to construct OOP framework atop of GOOPS. It might not be the simplest
solution, but I find it promising

  * It introduces a very strong, almost Linnaean, type system to Scheme,
where it seems out of place. I see no principal reason for such
classification. I don't declare my numbers in Scheme; why should I
declare my object types?

I don't think I understand. There is no strong type system, and
there's no need to declare object types. The types are mainly for
convinience -- to allow you to implement the same interfaces for
different objects.



Re: A couple of questions about goops method parameters

2014-09-05 Thread Taylan Ulrich Bayirli/Kammer
Marko Rauhamaa ma...@pacujo.net writes:

 Dynamic programming languages lack a true, efficient dot notation.

If with a true, efficient dot notation you mean for example C structs,
then records fill that role except for using accessor procedures instead
of syntax.

(Under the right conditions, usage of records could compile to direct
O(1) memory access (pointer+offset), just like usage of vectors.  Arrays
and structs in C are in direct analogy to vectors and records in Scheme;
the only difference being Scheme's general requirement of type-checks.)

Though after pondering a bit I realized that it indeed seems impossible
to compile (.bar foo) (could result from foo[.bar] via SRFI-105)
into the correct memory offset, if there are multiple record types each
with a '.bar' field, because it's not statically known which record type
'foo' has.  Maybe that's exactly what you meant.

Taylan



Re: A couple of questions about goops method parameters

2014-09-05 Thread Marko Rauhamaa
Panicz Maciej Godek godek.mac...@gmail.com:

 2014-09-05 22:44 GMT+02:00 Marko Rauhamaa ma...@pacujo.net:
 However, objects, in my opinion, are the antithesis of tuples.
 Objects are the focal points of methods. Whether the black box
 contains data and in what form is none of the rest of the world's
 concern.

 Apparently our views on the essence of OOP differ. I perceive an
 object as an aggregation of properties, and a set of methods I would
 call an interface. Perhaps to you doing OOP is about defining
 interfaces, and to me it's more about aggregating properties. I
 wouldn't say that anyone of us is more right than the other.

There's no point arguing about terminology. All I want to say is that
my OOP is desirable to me, your OOP is something I want to steer
away from.

I don't need interfaces as first-class entities in an object system.
Ducktyping involves less clutter and is more generic.

  * [GOOPS] introduces a very strong, almost Linnaean, type system to
Scheme, where it seems out of place. I see no principal reason for
such classification. I don't declare my numbers in Scheme; why
should I declare my object types?

 I don't think I understand. There is no strong type system, and
 there's no need to declare object types. The types are mainly for
 convinience -- to allow you to implement the same interfaces for
 different objects.

The types are a great inconvenience, syntactically and conceptually.
Syntactically, your GOOPS method definitions make your Scheme code look
like Pascal with the class names sprinkled among the parameters.
Conceptually, the classes force me to put objects into buckets that
don't correspond to my thought processes. Even Java offers anonymous
classes for the purpose.


Marko



Re: A couple of questions about goops method parameters

2014-09-05 Thread Marko Rauhamaa
Taylan Ulrich Bayirli/Kammer taylanbayi...@gmail.com:

 Though after pondering a bit I realized that it indeed seems impossible
 to compile (.bar foo) (could result from foo[.bar] via SRFI-105)
 into the correct memory offset, if there are multiple record types each
 with a '.bar' field, because it's not statically known which record type
 'foo' has.  Maybe that's exactly what you meant.

Yes.

It is amusing, though, that C originally suffered from the same issue:
the struct field offsets were global linker objects. That's why to this
day, unix/linux C structs have ugly field prefixes:

struct timeval {
time_t  tv_sec;
suseconds_t tv_usec;
};

struct timezone {
int tz_minuteswest;
int tz_dsttime;
};

struct linger {
int l_onoff;
int l_linger;
};

struct sockaddr_in {
sa_family_tsin_family;
in_port_t  sin_port;
struct in_addr sin_addr;
};

struct in_addr {
uint32_t   s_addr;
};

struct iovec {
void  *iov_base;
size_t iov_len;
};

and so on...


Marko



Re: A couple of questions about goops method parameters

2014-09-03 Thread Carlos Pita
 directly call initialize? In any case, why is this so? Wouldn't it be
 better for initialize to just get the unpacked argument list? This
 perplexes me.

I've been thinking about this, and lurking at the tinyclos
implementation, and then reading the cltl sections about initialization
in clos. Despite the fact that clos make-instance indeed *apply* the
initargs when calling initialize-instance, thus unpacking/destructuring
the initargs list, everything in the specification seems to imply a
plist style of usage. Even the name part of a name-value pair is used to
choose between (i) direct initialization of the corresponding slot or
(ii) calling the initialize-instance method with the name-value
pair. So, all in all, the usage implied is akin to dealing with a (name
value name value ...) list argument in goops or tinyclos.

All this seems specifically oriented to slot initialization, not to
general construction of a new instance while preserving some class
invariant imposed to the internal data/slots (please, notice that my
interest here is not about encapsulation or access control matters). So
maybe I'm suffering from a paradigm mismatch kind of thing, as I'm
trying to fit initialize into the usual OOP concept of constructor. From
this perspective initialize (and initialize-instance) looks to me like
erotic lingerie for slots (no pun intended, really :)), as maybe it
isn't completely transparent but it's surely translucent regarding the
underlying slots. The focus seems to be at a lower level of abstraction
than the level the usual constructor operates in. I'm aware of virtual
slots and, of course, of the possibility of implementing a custom
initialize method, but these solutions only buy some degrees of freedom
around the slot initializing focus: virtual slots still looks like slots
and the argument to initialize is still a list, presumably of slot
name-value pairs. I'm also aware of the possibility of defining read
only slots but, again, this is not generally enough to offer convenient
ways of construction that preserve some desired invariant.

So, a question to the experienced lispers here, a question that's not
specifically guile or goops or scheme related. Is the make (or
make-instance) way of constructing a new instance usually exposed to the
final user? Or a factory function, operating at a higher level of
abstraction, is intended to wrap the lower level, slot-fillig oriented,
call to make? In this case, a custom initialize method implementation
should be seen more as a complement to make than as a proper
constructor/factory.

(Moreover, the visibility and access of constructor/factory functions
are easily controlled using the module system although, as I've said
before, that's not my interest here).

Best regards
--
Carlos



Re: A couple of questions about goops method parameters

2014-09-03 Thread Panicz Maciej Godek
Howdy,

 How do you typically implement a custom initialization method, then?
 Using pattern matching? Maybe ice-9 optargs? Maybe apply? Maybe you
 directly call initialize? In any case, why is this so? Wouldn't it be
 better for initialize to just get the unpacked argument list? This
 perplexes me.

I'm not sure if I get the question right, but you usually overload the
initialize method (which calls (next-method)) and use the
let-keywords form if you want to add additional initialization
parameters

 2) What is the relationship between the lambda* family and methods?
 Are methods restricted in the sense that they can't aspire to get the
 greater flexibility of lambda* parameter handling? Maybe because of
 the way dispatching is done?

This is a good question and I'd like to know the answer myself,
but it seems to me that GOOPS methods and keyword arguments are
simply incompatible. Obviously you can obtain default arguments in GOOPS
quite easily:

(define-method (f (x t1) (y t2))
  ...)

(define-method (f (x t1))
  (f x default-y-value))

(define-method (f)
  (f default-x-value))

One could also come up easily with a macro that allows to expand

(define-method/default (f (x t1 default-x-value) (y t2 default-y-value))
  ...)

to the above code. But I don't think that the goops dispatcher was
anyhow suited for the keyword arguments (I could be wrong, though)



Re: A couple of questions about goops method parameters

2014-09-03 Thread Marko Rauhamaa
Carlos Pita carlosjosep...@gmail.com:

 So, a question to the experienced lispers here, a question that's not
 specifically guile or goops or scheme related. Is the make (or
 make-instance) way of constructing a new instance usually exposed to
 the final user? Or a factory function, operating at a higher level of
 abstraction, is intended to wrap the lower level, slot-fillig
 oriented, call to make? In this case, a custom initialize method
 implementation should be seen more as a complement to make than as a
 proper constructor/factory.

I saw the light and left goops behind. I built a simple system:

 * Not slot-centric but method-centric.

 * No classes, only objects.

IMO, the end result is more schemey than Goops.

It contains:

(make-object parentage . methods)

where

   parentage is #f, an object or a list of objects

   methods contains procedures, or name-procedure pairs

Example:

   (define (point .x .y)
 (define (x) .x)
 (define (y) .y)
 (make-object #f x y))

   (let ((point (point 7 8)))
 (point #:y))
   = 8

Marko



Re: A couple of questions about goops method parameters

2014-09-03 Thread Carlos Pita
http://www.aiai.ed.ac.uk/~jeff/clos-guide.html

and

http://permalink.gmane.org/gmane.lisp.cl-pro/24

support the make as implementation detail view.

Some excerpts:

It's often a good idea to define your own constructor functions, rather
than call make-instance directly, because you can hide implementation
details and don't have to use keyword parameters for everything. For
instance, if you wanted the name and age to be required, positional
parameters, rather than keyword parameters, you could define

(defun make-person (name age)
  (make-instance 'person :name name :age age))

[Notice how more convolved implementing the same using initialize would be]
-

In addition to this, you'd use a factory function, rather than having
the client call make-instance, to hide the CLOS nature of the type.
 On Sep 3, 2014 1:47 PM, Marko Rauhamaa ma...@pacujo.net wrote:

 Carlos Pita carlosjosep...@gmail.com:

  So, a question to the experienced lispers here, a question that's not
  specifically guile or goops or scheme related. Is the make (or
  make-instance) way of constructing a new instance usually exposed to
  the final user? Or a factory function, operating at a higher level of
  abstraction, is intended to wrap the lower level, slot-fillig
  oriented, call to make? In this case, a custom initialize method
  implementation should be seen more as a complement to make than as a
  proper constructor/factory.

 I saw the light and left goops behind. I built a simple system:

  * Not slot-centric but method-centric.

  * No classes, only objects.

 IMO, the end result is more schemey than Goops.

 It contains:

 (make-object parentage . methods)

 where

parentage is #f, an object or a list of objects

methods contains procedures, or name-procedure pairs

 Example:

(define (point .x .y)
  (define (x) .x)
  (define (y) .y)
  (make-object #f x y))

(let ((point (point 7 8)))
  (point #:y))
= 8

 Marko



A couple of questions about goops method parameters

2014-09-02 Thread Carlos Pita
Hi all,

I've some questions about parameter handling in goops methods:

1) initialize takes the initargs argument as a list, because of the
way make-instance is defined. But the documentation states:

In theory, initarg … can have any structure that is understood by
whatever methods get applied when the initialize generic function is
applied to the newly allocated instance.

One could think this implies that initargs won't necessarily be packed
as a list. Indeed, that would be very convenient and sensible for
custom initialization methods. But make-instance is implemented as:

(define-method (make-instance (class class) . initargs)
  (let ((instance (allocate-instance class initargs)))
(initialize instance initargs)
instance))

So one would need to rewrite it in order to apply initargs, or
something like that, in order to unpack the list.

How do you typically implement a custom initialization method, then?
Using pattern matching? Maybe ice-9 optargs? Maybe apply? Maybe you
directly call initialize? In any case, why is this so? Wouldn't it be
better for initialize to just get the unpacked argument list? This
perplexes me.

2) What is the relationship between the lambda* family and methods?
Are methods restricted in the sense that they can't aspire to get the
greater flexibility of lambda* parameter handling? Maybe because of
the way dispatching is done?

Thank you very much in advance for any help.

Best regards
--
Carlos