guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SLiM graphical login manager and keyboard layout


From: Ludovic Courtès
Subject: Re: SLiM graphical login manager and keyboard layout
Date: Tue, 22 Oct 2019 14:36:06 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Hello Tanguy,

Tanguy Le Carrour <address@hidden> skribis:

> Le 10/18, Diego Nicola Barbato a écrit :
>> Tanguy Le Carrour <address@hidden> writes:
>> >            (service slim-service-type
>> >              (slim-configuration
>> >               (xorg-configuration
>> >                (xorg-configuration
>> >                 (keyboard-layout keyboard-layout))))))
>> >
>> >
>> > I don't understand the "double" `xorg-configuration`, though! ^_^'
>> 
>> The outer 'xorg-configuration' is a field of the 'slim-configuration'
>> data type.  The inner 'xorg-configuration' is itself a data type
>> representing the Xorg configuration (with its 'keyboard-layout' field
>> set to the value of 'keyboard-layout').
>
> Thanks for the clarification!
> All of this LISP/Scheme/Guile is still a bit magical to me! How does one makes
> the difference between field assignment and data type "instanciation"? ^_^'
> How does the interpreter know that the same "word" means two different
> things?!

There are several rules.  The most important one is lexical scope: when
you see an identifier, it always refers to the binding in its lexical
scope.  So there are no bad surprises:

  (let ((* +) (x 42))  ;here ‘+’ is a “free variable”—i.e., not in scope
    (let ((x 7))
      (* x x)))
  => 14

Then there are “special forms” (macros) that can introduce new bindings
like ‘let’.  Macros are always* “referentially transparent” (or
“hygienic”), which means notably that they only introduce bindings that
you explicitly typed in, and they cannot capture bindings that you did
not explicitly provide them as an argument:

  (let ((x 3))
    ;; Here ‘x’ is defined.
    …)

  (operating-system
    (keyboard-layout …)
    ;; Here ‘keyboard-layout’ is defined, because ‘operating-system’
    ;; expands to something like:
    ;;
    ;;  (let* ((keyboard-layout …) (next-field …) …) …)
    )

The rules are unambiguous.  I understand it takes some getting used to
it, but the general idea is that scoping behaves “like you’d expect.”

HTH!

Ludo’.

* It’s possible to write so-called “unhygienic” macros that would, for
  instance, forcefully create bindings that don’t appear in the source,
  but that’s considered bad practice and we don’t do that in the Guix
  code base.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]