`position' in rep...?

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

`position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Hi all,

just a small question, whether I'm blind, or whether rep really doesn't
ship a function like `position'.

so `nth' gives the the value of the nth element:

(setq mylist '("Crux" "StyleTab" "get-S-tabbed"))
(nth 1 mylist)

=> StyleTab

but now for the opposite? other lisps do ship `position':

(position "Crux" mylist)

=> 0

Now it seems to me that REP does not ship a position function? Atleast I
couldn't find one in the docs neither via `git grep'. I think that's
essential, so I'm sure it's somewhere. Or... did John expect everyone to
loop through lists?

Chris

Re: `position' in rep...?

by nowan@nowan.org :: Rate this Message:

| View Threaded | Show Only this Message

Christopher Roy Bratusek <nano@...> writes:

> just a small question, whether I'm blind, or whether rep really
> doesn't ship a function like `position'.
>
> so `nth' gives the the value of the nth element:
>
> (setq mylist '("Crux" "StyleTab" "get-S-tabbed"))
> (nth 1 mylist)
>
> => StyleTab
>
> but now for the opposite? other lisps do ship `position':
>
> (position "Crux" mylist)
>
> => 0
>
> Now it seems to me that REP does not ship a position function? Atleast
> I couldn't find one in the docs neither via `git grep'. I think that's
> essential, so I'm sure it's somewhere. Or... did John expect everyone
> to loop through lists?

I don't know of such a thing, but how often would you really need to
know the position of an element?  In most cases I can think of where you
might use a position "member" would do what you need without the use of
a position.

--
Jeremy Hankins <nowan@...>

Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Am 29.05.2011 16:03, schrieb Jeremy Hankins:

> Christopher Roy Bratusek<nano@...>  writes:
>
>> just a small question, whether I'm blind, or whether rep really
>> doesn't ship a function like `position'.
>>
>> so `nth' gives the the value of the nth element:
>>
>> (setq mylist '("Crux" "StyleTab" "get-S-tabbed"))
>> (nth 1 mylist)
>>
>> =>  StyleTab
>>
>> but now for the opposite? other lisps do ship `position':
>>
>> (position "Crux" mylist)
>>
>> =>  0
>>
>> Now it seems to me that REP does not ship a position function? Atleast
>> I couldn't find one in the docs neither via `git grep'. I think that's
>> essential, so I'm sure it's somewhere. Or... did John expect everyone
>> to loop through lists?
> I don't know of such a thing, but how often would you really need to
> know the position of an element?  In most cases I can think of where you
> might use a position "member" would do what you need without the use of
> a position.
You would need it for every GtkComboBox in SawfishConfig, to set the
initial value, to what the user previously selected (or to what the
default value is).

Chris

Re: `position' in rep...?

by nowan@nowan.org :: Rate this Message:

| View Threaded | Show Only this Message

Christopher Roy Bratusek <nano@...> writes:

> You would need it for every GtkComboBox in SawfishConfig, to set the
> initial value, to what the user previously selected (or to what the
> default value is).

Ah, ok.  Then yeah, I think you are supposed to loop through. ;)  I'm
not sure that rep really needs a position function -- in most cases it's
just going to encourage non-lispy lisp programming, I think.  In those
situations where you need one just include something like this:

(define (position item l)
  (let loop ((rest l)
             (i 0))
       (if (equal item (car rest))
           i
         (loop (cdr rest) (1+ i)))))

Perhaps equal should be eq, depending on how you're using it...?

--
Jeremy Hankins <nowan@...>

Re: `position' in rep...?

by nowan@nowan.org :: Rate this Message:

| View Threaded | Show Only this Message

Jeremy Hankins <nowan@...> writes:

> Christopher Roy Bratusek <nano@...> writes:
>
>> You would need it for every GtkComboBox in SawfishConfig, to set the
>> initial value, to what the user previously selected (or to what the
>> default value is).
>
> Ah, ok.  Then yeah, I think you are supposed to loop through. ;)  I'm
> not sure that rep really needs a position function -- in most cases it's
> just going to encourage non-lispy lisp programming, I think.  In those
> situations where you need one just include something like this:
>
> (define (position item l)
>   (let loop ((rest l)
>              (i 0))
>        (if (equal item (car rest))
>            i
>          (loop (cdr rest) (1+ i)))))
>
> Perhaps equal should be eq, depending on how you're using it...?

Uh, make that:

(define (position item l)
  (let loop ((rest l)
             (i 0))
       (if (equal item (car rest))
           i
         (if rest
             (loop (cdr rest) (1+ i))))))

So as to avoid those nasty infinite loops.... :P

--
Jeremy Hankins <nowan@...>

Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Am 29.05.2011 16:40, schrieb Jeremy Hankins:
> Christopher Roy Bratusek<nano@...>  writes:
>
>> You would need it for every GtkComboBox in SawfishConfig, to set the
>> initial value, to what the user previously selected (or to what the
>> default value is).
> Ah, ok.  Then yeah, I think you are supposed to loop through. ;)  I'm
> not sure that rep really needs a position function -- in most cases it's
> just going to encourage non-lispy lisp programming, I think.  In those
> situations where you need one just include something like this:

Including it in sawfish.gtk.widgets should be enough. I just wondered,
why other LISP
(Emacs/Common-Lisp) do have one, but we don't. ;)

Chris

Re: `position' in rep...?

by Teika kazura :: Rate this Message:

| View Threaded | Show Only this Message

On Sun, 29 May 2011 16:47:07 +0200, Christopher Roy Bratusek wrote:
> Including [position] in sawfish.gtk.widgets should be enough.

Please put it in librep. There're too many wm.misc functions which
should have been put in librep.

Regards,
Teika (Teika kazura)

# Installed sawfish-1.8.90. Thanks.


Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Am 01.06.2011 09:56, schrieb Teika Kazura:

> On Sun, 29 May 2011 16:47:07 +0200, Christopher Roy Bratusek wrote:
>> Including [position] in sawfish.gtk.widgets should be enough.
> Please put it in librep. There're too many wm.misc functions which
> should have been put in librep.
>
> Regards,
> Teika (Teika kazura)
>
> # Installed sawfish-1.8.90. Thanks.
>

OK. There's now rep.util.misc which atm contains string->symbol and
position (both from sawfish.gtk.widget).
Storing here comes in hand, as several widgets in
sawfish.gtk/cfg.widgets.* will (in the future) need position func, too.

So if you have any more you would like to see in REP, leave a note.

Chris

Re: `position' in rep...?

by Teika kazura :: Rate this Message:

| View Threaded | Show Only this Message

On Thu, 02 Jun 2011 22:24:27 +0200, Christopher Roy Bratusek wrote:
>>> Including [position] in sawfish.gtk.widgets should be enough.
>> Please put it in librep.>>
>
> OK. There's now rep.util.misc which atm contains string->symbol and
> position

It's not pushed yet, (only the changelog) but before you do, let me
comment a bit.

string->symbol: `intern' may be what you want.
position: If it's only what you want, (= if string->symbol turns out
 to be unnecessary) than you can put it in rep/data.jl. Then all you
 have to import is 'rep'. In another words, you don't have to import
 any extra module, since it's always loaded. Don't forget to add
 it to 'export-bindings'.

Teika (Teika kazura)


Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Am 04.06.2011 09:26, schrieb Teika Kazura:
> On Thu, 02 Jun 2011 22:24:27 +0200, Christopher Roy Bratusek wrote:
>>>> Including [position] in sawfish.gtk.widgets should be enough.
>>> Please put it in librep.>>
>> OK. There's now rep.util.misc which atm contains string->symbol and
>> position
> It's not pushed yet, (only the changelog) but before you do, let me
> comment a bit.
>
> string->symbol: `intern' may be what you want.

I know and at first I thought as you, that it's unnecessary, but I
thought about the wording,
in some cases, eg: in SawfishConfig -just as I did recently-
string->symbol is way more
intuitive compared to intern. (of course it's the same, but then you
read `intern' you think
about some internal symbol, not a conversion). So I thought that 1 line
extra-code won't
hurt that much :)

> position: If it's only what you want, (= if string->symbol turns out
>   to be unnecessary) than you can put it in rep/data.jl. Then all you
>   have to import is 'rep'. In another words, you don't have to import
>   any extra module, since it's always loaded. Don't forget to add
>   it to 'export-bindings'.

There's already one more I found which is spread several times of
Sawfish 3 or 4: beautify-symbol-name,
(if I'm right beautfiy-keymap-name is just a minor variation of it)  and
I think it should be in REP.

> Teika (Teika kazura)
>
Chris

Re: `position' in rep...?

by nowan@nowan.org :: Rate this Message:

| View Threaded | Show Only this Message


I wrote a version of the position function that would work with circular
lists, since the other one will start an infinite loop if you give it a
circular list.  I've included the function below, but it turns out that
infinite lists are only semi-supported -- calling length, or even
evaluating them in sawfish-client, causes an infinite loop.  According
to the docs (where I should have looked first) only cons, car, cdr,
rplaca, rplacd, nth, and nthcdr can be used on circular lists.

In short: I don't know that it's worth it to fix it elsewhere, even if
we end up staying with rep, but if it's of any interest here's a version
of position that wont choke on infinite lists.

(define (position item l)
  (let ((start l))
    (let loop ((rest l)
               (i 0))
         (if (equal item (car rest))
             i
           (unless (or (null rest)
                       (and (/= 0 i)
                            (eq rest start)))
             (loop (cdr rest) (1+ i)))))))

--
Jeremy Hankins <nowan@...>

Re: `position' in rep...?

by Timo Korvola-2 :: Rate this Message:

| View Threaded | Show Only this Message

On Monday 06 June 2011 23:19:43 Jeremy Hankins wrote:
> I wrote a version of the position function that would work with
> circular lists, since the other one will start an infinite loop if
> you give it a circular list.

Many functions do. Basically anything that loops through the elements of
a list will get stuck. Your fix does not work either if the list cycles
back not to its head but some later element. Cyclic lists are rare and
it has not been deemed useful to check for them in every library
function. Common Lisp has list-length that checks for cycles (standard
length does not).

A useful extension for position would be vector support. Because
indexing lists is inefficient, position should preferably be used with
vectors.

--
        Timo Korvola <URL:http://www.iki.fi/tkorvola>

[sawfish] Re: `position' in rep...?

by Eli Barzilay :: Rate this Message:

| View Threaded | Show Only this Message

9 hours ago, Jeremy Hankins wrote:
>
> I wrote a version of the position function that would work with
> circular lists, since the other one will start an infinite loop if
> you give it a circular list.

That code is broken, as Timo points out.  See correct version below.


> I've included the function below, but it turns out that infinite
> lists are only semi-supported -- calling length, or even evaluating
> them in sawfish-client, causes an infinite loop.  According to the
> docs (where I should have looked first) only cons, car, cdr, rplaca,
> rplacd, nth, and nthcdr can be used on circular lists.

That's a bad state.  It means that doing some naive experimenting can
easily get your WM to die.  (And dynamic experimenting is one of
sawfish's great advantages.)


> In short: I don't know that it's worth it to fix it elsewhere, even
> if we end up staying with rep, [...]

The repl getting hung up is especially disturbing, and shouldn't be
hard to fix.  Other functions can trip into an infinite loop but at
least they're easier to break.


40 minutes ago, Timo Korvola wrote:
>
> Many functions do. Basically anything that loops through the
> elements of a list will get stuck.

There's no reason to let them get stuck.  In Racket, as in some other
Scheme implementations, `list?' is implemented correctly and will
return #f when given a cyclic list.  (This is specified in R5RS, which
even gives this example:

 (let ((x (list 'a)))
   (set-cdr! x x)
   (list? x))         ==>  #f

)  In such implementations there's an easy way to deal with cyclic
lists in a way that avoids infinite loops -- for example:

  (define (position item l)
    (unless (list? l) (error "bleh"))
    ... usual code, ignore infinite lists ...)

But of course dealing with potentially infinite lists is not much
harder.


> Your fix does not work either if the list cycles back not to its
> head but some later element.

Right -- checking if you get back to the beginning isn't going to
work.  The common way to deal with infinite lists is the "hare and
tortoise" method: iterate with two pointers, one advancing at twice
the speed of the other.  Here's a working implementation of `position'
using this:

  (define (position item l)
    (let loop ((slow l) (l l) (i 0))
      (cond ((not (consp l)) #f)
            ((equal item (car l)) i)
            (#t (let ((l (cdr l)) (i (1+ i)))
                  (cond ((not (consp l)) #f)
                        ((equal item (car l)) i)
                        ((eq l slow) #f)
                        (#t (loop (cdr slow) (cdr l) (1+ i)))))))))

This follows the common pattern for this method: the usual code is
written twice, and the slow pointer is checked and advanced once per
iteration.  Implementing `length' etc like this is easy, and it would
be nice if cyclic lists won't get basic things like that to crash
sawfish.

--
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Re: [sawfish] Re: `position' in rep...?

by nowan@nowan.org :: Rate this Message:

| View Threaded | Show Only this Message

Eli Barzilay <eli@...> writes:
> 9 hours ago, Jeremy Hankins wrote:
>>
>> I wrote a version of the position function that would work with
>> circular lists, since the other one will start an infinite loop if
>> you give it a circular list.
>
> That code is broken, as Timo points out.  See correct version below.

Yes, of course.  Thank you and Timo for explaining it.

>> I've included the function below, but it turns out that infinite
>> lists are only semi-supported -- calling length, or even evaluating
>> them in sawfish-client, causes an infinite loop.  According to the
>> docs (where I should have looked first) only cons, car, cdr, rplaca,
>> rplacd, nth, and nthcdr can be used on circular lists.
>
> That's a bad state.  It means that doing some naive experimenting can
> easily get your WM to die.  (And dynamic experimenting is one of
> sawfish's great advantages.)

Having killed my wm several times when experimenting with this, I can
certainly agree.  The contra position is that few people who don't have
at least some understanding of what they're doing are going to generate
a circular list, but it does seem to me that where we can eliminate the
possibility of crashing your wm we should.

>> In short: I don't know that it's worth it to fix it elsewhere, even
>> if we end up staying with rep, [...]
>
> The repl getting hung up is especially disturbing, and shouldn't be
> hard to fix.  Other functions can trip into an infinite loop but at
> least they're easier to break.

I say I don't know because I don't know how involved the changes to
librep that would fix this would have to be.  And if we are going to
switch away from rep at some point it may not be worth the effort to go
through and make the fixes, as well as possibly fixing bugs that crop up
elsewhere as a result of the fixes -- though I wouldn't expect many of
these.

As I see it this is a reasonably compelling reason to switch to a lisp
that's not specific to sawfish: more use-cases means more testing and
fewer gotchas like this one.  I've been ambivalent on the issue before,
but this has made me rethink my view.

[Interesting discussion of the right way to write 'position' snipped]

--
Jeremy Hankins <nowan@...>

Re: [sawfish] Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Again learned something :)

Still, your new version of `position' breaks SawfishConfig (in misc-1.9).

Chris

Re: [sawfish] Re: `position' in rep...?

by Eli Barzilay :: Rate this Message:

| View Threaded | Show Only this Message

Three hours ago, Christopher Roy Bratusek wrote:
> Again learned something :)
>
> Still, your new version of `position' breaks SawfishConfig (in
> misc-1.9).

If by "your version" you mean the one I wrote, then please tell me how
it breaks.  It's been a while since I wrote sawfish code so it's
likely that I made some stupid mistake.  (The method itself is valid,
and well used, that shouldn't be a problem.)

--
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Re: [sawfish] Re: `position' in rep...?

by Eli Barzilay :: Rate this Message:

| View Threaded | Show Only this Message

9 hours ago, Jeremy Hankins wrote:
> I say I don't know because I don't know how involved the changes to
> librep that would fix this would have to be.

The simplest thing to do when printing out a list is to use the same
trick and just abort with an error message, or print `...' when you
get back to the slow pointer.  A more sophisicated solution would be
to do the popular Lisp printout using `#1='s and `#1#'s, but that's
arguably an overkill.


> As I see it this is a reasonably compelling reason to switch to a
> lisp that's not specific to sawfish: more use-cases means more
> testing and fewer gotchas like this one.  I've been ambivalent on
> the issue before, but this has made me rethink my view.

+1.

--
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Re: [sawfish] Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Am 07.06.2011 23:37, schrieb Eli Barzilay:
> Three hours ago, Christopher Roy Bratusek wrote:
>> Again learned something :)
>>
>> Still, your new version of `position' breaks SawfishConfig (in
>> misc-1.9).
> If by "your version" you mean the one I wrote, then please tell me how
> it breaks.  It's been a while since I wrote sawfish code so it's
> likely that I made some stupid mistake.  (The method itself is valid,
> and well used, that shouldn't be a problem.)

Well, assume this:

sawfish-client

(setq mylist '("Crux" "StyleTab" "MXFlat"))
(position "Crux" mylist)
0

works. Now in SawfishConfig this code is used (with different
variable-names):

(gtk-combo-box-text-set-active widget (position value list))

widget is a GtkComboBoxText widget, value the usergiven (or fallback)
value of the setting represented by the widget (eg. frame-style), list
is the list given as options (see any 'choice or 'symbol defcustom in
Sawfish).

A GtkComboBoxText expects the index-number not the text, so position is
used to return it, with your version of position we get:

*** Bad argument: #<subr gtk-combo-box-set-active>, (), 2

so either position returns nothing or not an integer. As I now got the
time to test, I'll continue now:
New line of code before setting position:

write standard-output (format nil "*** value is: %d" x)

*** value is: #<non-number>

Againg with %s instead:

value is: flip-viewport

? from SawfishConfig it returns the value instead of the index-number.

corresponding code resides in sawfish.gtk.widget (choice and symbol
widgets), in misc-1.9 branch.

Regards,
Chris

Re: [sawfish] Re: `position' in rep...?

by Christopher Roy Bratusek-2 :: Rate this Message:

| View Threaded | Show Only this Message

Sorry, wrong code for printing the value... (If forgot that x is the
symbol),

    (write standard-output (format nil "value is: %s" (position x options)))

returns (), even though flip-viewport is part of options.

Now with:

   (write standard-output (format nil "value is: %s\n" (position x
options)))
   (write standard-output (format nil "list is: %s\n" options))

   value is: ()
   list is: (none/hot-spot viewport-drag flip-workspace flip-viewport
tile-windows)

Now I've seen the problem:

(a b c) Vs '(a b c)

Chris

Re: [sawfish] Re: `position' in rep...?

by Eli Barzilay :: Rate this Message:

| View Threaded | Show Only this Message

6 hours ago, Christopher Roy Bratusek wrote:

> Now in SawfishConfig this code is used (with different
> variable-names):
>
> (gtk-combo-box-text-set-active widget (position value list))
> [...]
>
> A GtkComboBoxText expects the index-number not the text, so position
> is used to return it, with your version of position we get:
>
> *** Bad argument: #<subr gtk-combo-box-set-active>, (), 2

Yes, if the value is not found, it returns false, which in rep is the
empty list.  If you can't rely on the value being found, then just
protect the use, either with a default:

  (gtk-combo-box-text-set-active widget (or (position value list) 0))

or by just not doing it:

  (let ((i (position value list)))
    (when i (gtk-combo-box-text-set-active widget i)))


> [...]
> corresponding code resides in sawfish.gtk.widget (choice and symbol
> widgets), in misc-1.9 branch.

I don't see this branch at git://git.gnome.org/sawfish


5 hours ago, Christopher Roy Bratusek wrote:
> [...]
> Now I've seen the problem:
>
> (a b c) Vs '(a b c)

That sounds like it was a different problem...

--
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!
< Prev | 1 - 2 | Next >