Arc Forumnew | comments | leaders | submit | almkglor's commentslogin

Hmm. Don't have time currently to think deeply about things, but how would you implement, say, an Arc-specified complex number (with the proviso that if mzscheme supports a complex number, you don't cheat and use that - you have to make the complex number in Arc).

And of course, you have to be capable of adding a non-complex number with a complex number, as well as multiply etc.

Then of course implement 3-d vectors, with real-imaginary-z components, with the implication that a complex number is simply a 3-d vector with z=0.

(Edit) As a final proviso, make the 3-d vectors and complex stuff into independent, separately loadable libraries. ^^ No loading one before the other. ^^ That way we can also check if it's possible for different pieces of code to interoperate using the proposed type system properly.

This, ultimately, is the problem when methods are stored with the object: what if a method acts on different objects? Which object's method should we use? It's okay for methods which act on only one object (such as 'car and 'cdr) but what about those that don't (such as '+ and '-)?

-----

3 points by cchooper 6459 days ago | link

It doesn't do multiple dispatch, so you can't really do all of this yet. Multiple dispatch could either be implemented in call or by putting the call implementation in the polymorph.

If you put it in the polymorph then you have to reimplement it each time, which is bad. On the other hand, you can customise how multiple dispatch works for different types. You'd probably need that for arithmetic, because you always have to coerce values to the most general type (e.g. integers to rationals). I don't know any other types that do that. It's a special case.

Vector types could perhaps be implemented by supporting the interface '(vector n) where n is the dimension. Then your complex numbers could implement '(vector 3) or something. Dependent typing is not something I've thought about. Maybe it can be done.

Another way of doing this could be to have alternatives to call. You could have a simple single-dispatch call, then another (multi-call) that works like multiple-dispatch in CLOS (using inheritance hierarchies to choose a method), then another one that coerces everything to the 'most general type' (whatever that means in the context).

-----

2 points by almkglor 6458 days ago | link

"I don't know any other types that do that. It's a special case."

Suppose I'm modelling a starfield for a computer game, and I have ships and missiles flying around. I then, quite reasonably enough, have a (collide a b) function that I call whenever I notice that one of the ships collides with a something else. We could have ships colliding with ships, or colliding with missiles, or missiles colliding wiht other missiles. Worse, we've relegated our collision detecting code to a loop that goes through the list of game elements, so we can't exactly say that a will be a ship or a missile (or even an asteroid). Different things will happen based on the type of object - missiles just cancel each other out, but ships have to explode convincingly, and of course there's a special handling for the player's own ship (because it's game over then).

It's not a web app, but hey ^^

So multiple dispatch is in fact a pretty good strength in CLOS, and it's generally done over the is-a-ness of the object ^^.

-----

1 point by cchooper 6457 days ago | link

That was in reference to coercion, not multiple dispatch. I actually think the whole thing would be pretty useless without multiple dispatch.

-----

2 points by almkglor 6457 days ago | link

Ah, ok. So: how do we implement multiple dispatch when functions are attached to objects? ^^

-----

1 point by cchooper 6456 days ago | link

I'm working on it :)

-----

1 point by almkglor 6455 days ago | link

Hmm. Any ideas yet? I can't think of any so far.

Somehow I feel that having two layers - an is-a type attached to an object, and has-a interface semantics attached to functions on an object, might work. Basically a type declares a set of has-a interfaces, and provides (using multiple dispatch) the functions used to implement the interface. So an object is-a ship and is-a missile and is-a asteroid and is-a player-ship, and each of those types has-a collideable interface, defining how different objects react to being bashed against one another.

Or not. Dunno.

-----


(1) Agree

(2) Could be done, and have interfaces simply act as a shortcut way of saying "I have (for objects) or need (for functions) the following: a, b, c, and d"

(4) LOL. We're making an informally-specified, ad-hoc, bug-ridden implementation of half of CLOS. ^^

-----

2 points by sacado 6459 days ago | link

"We're making an informally-specified, ad-hoc, bug-ridden implementation of half of CLOS"

That's what I thought when I was thinking about solutions for these problems :)

I think (1) could be solved simply by using redef on each polymorphic function : if car becomes polymorphic, just encapsulate the desired behavior in a new definition of car that will do the dynamic dispatch for you. If you want a specific version of car (e.g. the array implementation), just call it explicitly : (array-car x) .

-----


Actually, I am arguing for a "contains as a part" semantics. arc.arc does have polymorphism - there are functions that work on sequences like lists, strings, and tables. The problem, however, is that some of them don't work on user-defined types without munging with 'isa.

What I'm proposing is abstracting some very "basic operations" such as 'car and 'cdr, put them in some "types" (really closer to type classes/abstract base class), and then have the built-in types "contain as a part" the "basic operation type". Then the arc.arc polymorphic functions will work based on the "basic operation type" instead of the actual is-a type, and user-defined types don't have to munge 'isa.

-----

1 point by absz 6459 days ago | link

But if you think about it as an abstract base class/mixin/interface, then the standard terminology is "is-a". For instance, in Ruby:

  module MyMixin # Like an interface
    ...
  end
  
  class MyClass
    includes MyMixin # Like "implements MyMixin"
    ...
  end
  
  foo = MyClass.new
  if foo.is_a? MyMixin
    puts "is-a"
  else
    puts "has-a"
  end
  # Output: "is-a"
I'd rather see the "basic types" not as a collection of basic components, but as a collection of basic interfaces one can implement, or basic type classes one can be a member of, or what-have-you; what I'd really rather do is duck most of it, like Ruby does. If I can define car and cdr for my type, map should work seamlessly.

Regardless, it sounds like a lot of the voices here are in agreement over some common set of the features this plan proposes, which is a good thing. Perhaps we should set the naming quibbles aside for now and try to flesh that out. Or perhaps we should settle on a name for what we are about to flesh out. Either way, it looks like something good could well emerge from this thread.

-----

2 points by almkglor 6459 days ago | link

I vote we settle on a name first, because we need it to refer to stuff when we talk about it ^^

-----

6 points by almkglor 6459 days ago | link | parent | on: A wiki, in Arc: Arkani now on Anarki

Yes. It's even in a file named wiki-arc, to make it even more confused with arc-wiki

-----

3 points by almkglor 6460 days ago | link | parent | on: pageonetimes.com - powered by arc

Much, much better. Would you mind some more additional (hopefully constructive) criticisms?

-----

2 points by antiismist 6459 days ago | link

Yeah keep it coming. I really appreciate the feedback

-----

3 points by almkglor 6459 days ago | link

My current major objection is the size of the headlines, which I think should be larger. Alternatively make the summaries shorter. How do you generate the summaries?

Also, the bottommost part appears too ragged for me. Some amount of measurement may be possible.

A final suggestion: perhaps make the highest-ranked 1 or 2 headlines near the top of the page in even larger text (in addition to the headline+summary currently on the page.). The top headlines in large text should maybe be just headlines, no summary, but put an anchor link to the headline+summary version in the rest of the page. Basically, something a little like the banner headline of the front page of a newspaper.

-----

2 points by antiismist 6459 days ago | link

Thanks for the feedback. The summaries are put in manually when the comment is posted, so nothing fancy. In practice one just has to remember to grab some text before using the bookmarklet (which fills in the rest).

A lot of people have said that the ragged bottom takes away a bit from the look and feel. There doesn't seem to be an easy way to fix that. The best I can come up with is to try and estimate the line height of each story, and if it exceeds a certain amount then truncate it, but only if it is on a page w/ other stories.

I'll play around with the top-top headlines idea. Is it inline with the look and feel of newspapers.

Thanks for the suggestions!

-----

Edit: The headlines are now bigger. It is better, thanks!

I moved them from 1em to 1.25em after trying it via firebug.

-----

2 points by almkglor 6459 days ago | link

Regarding summaries, I think it would be possible to actually pull some text using Arc (although currently there seems to be no decent way to open a client connection, and certainly there don't seem to be any libraries for client-side HTTP). Of course the summarization would have to be done too. Hmm.

-----

1 point by antiismist 6459 days ago | link

What I could do is if you use the bookmarklet, then it will pull in a best guess as to what the summary is and put it into the box. Then the user can edit that if they want. That wouldn't be too hard.

With ajax I could do the same thing once the user fills in the url.

-----

3 points by almkglor 6459 days ago | link

IMO the hard part is the "best guess". ^^ I've been looking for papers about summarization and haven't found much. Hmm. Maybe look at the title and try to fetch words around words in the title, i.e. use the title's terms as search terms.

-----

3 points by antiismist 6459 days ago | link

There is an easy way and a hard way to do it. For most articles, if you take the first element in the DOM that is a paragraph and contains above a certain number of words, then I am guessing that would most times be the leader paragraph.

The second easy way is to do the above most of the time, but have some site-specific things that are used instead.

You could also use some classifying software to ID the proper paragraph. You could have a training set of all the descriptions that have been on the site before, and find text that most matches that text, and use that. Or find the first bit of text that matches beyond a certain threshold, and use that.

The hardest way is to automatically generate a summary. I work in the automated document analysis business, and this is indeed pretty hard to do.

-----

3 points by almkglor 6460 days ago | link | parent | on: Hash element as lvalue

If you're really interested in creating your own collection objects, such as building your own table-like structure, please see my series of "Create your own collection", listed in order of posting:

http://arclanguage.org/item?id=3595

http://arclanguage.org/item?id=3698

http://arclanguage.org/item?id=3762

http://arclanguage.org/item?id=3858

-----


"objects-have-one-type" model helps with nex3's defm:

  (defm something ((t f scanner))
    (do-something-on-scanner f))
  (defm something ((t f cons))
    (do-something-on-real-cons-cell f))
In this case, if we pass an object that is-a scanner and is-a cons, which method gets called?

This is the main reason I'm advocating is-a and has-a separation. We can say that an object is-a 'cons cell and has-a scanner. If something requires that an object is-a real, element-pointer-and-next-pointer 'cons cell, as opposed to somethingthing that requires that an object has-a 'car and 'cdr, we can make the distinction.

So we can say that an object is-a 'cons cell - it's what it really is, what it's implemented with. However, a 'cons cell has-a scanner interface, and if it's proper it has-a list interface, etc.

Separating is-a and has-a could also be useful for optimization of basic parts.

For example, a basic non-optimized diff algorithm might operate on has-a 'scanner, and use 'car and 'cdr operations. However a string-scanner is really just a wrapper around a string and an index into the string, as well as the string's length. Each 'string-scanner object contains three slots: one for the string, one for the index, and one for the length. This applies to each 'cdr on a string-scanner.

Now suppose we have a version of the diff algo which specifically detects if an object is-a string-scanner. It destructures the string-scanner into the string, index, and end, and instead of carrying around a triple of (string, index, length) it only carries the index, leaving string and length into local variables. This reduces memory consumption to only one-third.

(Note that the diff algo I posted a while back actually keeps entire sections of the list, in order to properly scan through their differences; that is, it keeps several scanners)

-----

5 points by sacado 6460 days ago | link

Hmm, I think there are 2 really different concepts here :

- type declaration of real-implementation (what you call "is-a"),

- type declaration in the sense of "capabilities" an object has (what you call has-a).

I think they should really be distinguished. The former is about optimized compilation, the latter about which functions can be applied to a given object.

But optimization is linked to variables (e.g. "in this block n always holds an integer, s always holds a string and l is always a cons) and does not need to be declared until you want to compile something.

On the opposite, capabilities are linked to values (e.g., "n, s and l are all scanners, they all have scanner capabilities, you can apply car and cdr to all of them. This is currently true, but could change if values referenced by n, s or l change). These are mandatory, and have to be known dynamically (this is not a declaration in the static meaning, they can even change later). When you apply car to a variable, you must know if its attached value can answer it (and eventually how).

  (= str (string-scanner "foo bar baz"))
  (type str)
  -> (scanner string)

  (def scan (s)
    (if (no s)
      ""
      (cons (foo (car s)) (cdr s))))
There, the values held by s are considered as a scanner and a string, that is, car and cdr can be applied to them. A dispatch algorithm is applied to them on the moment we need it. If, at any moment, an object held by s cannot be applied the method car or cdr, we have an error. Until we want more speed, that's enough.

Now suppose we want more. All we have to do is :

  (def scan (s)
    (istype string-scanner s
      (if (no s)
        (cons (foo (car s) (cdr s)))))
That way, for optimization purpose, we state that s only holds string-scanner objects. It does not even have to care with the annotations you added to the value (or values) held by s. If an object held by s is not really a string-scanner, well, anything could happen.

I might be wrong, but I think super-optimizing CL compilers work that way. You say them "optimize that function, and btw, this var always holds strings, don't even bother checking and dispatching the right function".

-----

4 points by almkglor 6460 days ago | link

Quite accurate. The main thing is that I think people should use has-a for everyday programming, and only use is-a if absolutely necessary, e.g. optimization.

My second proposal, probably lost somewhere in the confusion, is that has-a information would be connected to an object's is-a type.

-----

4 points by almkglor 6461 days ago | link | parent | on: String madness?

The return value of 'system is always nil I think.

I'm not sure if wrapping it in a (tostring ...) form will work

Edit: It does:

  arc> (system "echo foo")
  foo
  nil
  arc> (tostring (system "echo foo"))
  "foo\n"

-----

3 points by almkglor 6461 days ago | link

Probably better formatted this way:

  (tostring:system "perl whatever")

-----

1 point by wfarr 6461 days ago | link

That did it. Thanks greatly!

-----

2 points by almkglor 6460 days ago | link

Welcome, I'm glad you actually bothered to put me up in your blog ^^

That said it would probably be a good project to build some sort of decent parsing in Arc. It might be good to use raymyer's parser combinator library, which although intended to work on lists will probably also work on string scanners. That said while I have a general knowledge of parser combinators I haven't actually used them (although I did write a value-change-dump (.vcd) file parser which I suspect used parser combinator concepts before I even learned about parser combinators - it was plenty slow though).

The other concern is the real problem of namespace pollution, raymyers' code uses some very short names - alt, lit. Fortunately they're not macros; raymyers specifically introduced optional laziness via delay-parser in order to reduce macro namespace collision.

-----

1 point by wfarr 6460 days ago | link

I'd be more than glad to help in what (little) ways I can to get Arc's string libraries up to par so that Markdown could be truly reimplemented in it.

-----

1 point by almkglor 6461 days ago | link | parent | on: much much better arc logo

                  _
    .-.     .--  /
   /   \   /    |
  /     \ /      \_

-----

7 points by nex3 6461 days ago | link

The first thing I thought when I saw that was "snake?" Then "bouncing pac man?"

-----

2 points by tjr 6460 days ago | link

The first thing I thought of was that it spelled out "Arc", since this is a thread about Arc logos, and all... :-)

-----

2 points by nex3 6460 days ago | link

Ah, but I read from the "New Comments" view. I noticed the drawing long before I realized what thread it was in.

-----

1 point by Jesin 6459 days ago | link

        _  _
    /\ | \/ \
   /__\|_/
  |    | \
  |    |  \_/

-----

1 point by almkglor 6462 days ago | link | parent | on: Arc continuation puzzle

  11223
My guess ^^

The alternative is:

  1122222222222222222222222222222222222222222222222222222222^C

-----

More