# Function calls in keymap definition

**URL:** <https://community.keyboard.io/t/function-calls-in-keymap-definition/897>\
**Category:** Programming\
**Created:** [December 22, 2017, 8:51pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897 "2017-12-22T20:51:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 22, 2017, 8:51pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/1 "2017-12-22T20:51:00Z")

</div>

Is it possible to use a function call within the brace initializer that’s used to define the keymap in the sketch file? I’m thinking of trying an alternative to the somewhat awkward way of defining Qukeys that exists now, but it would require a function call that would take two `Key` values as parameters, and return a special `Key` value that encodes a serial number (via an incremented `static` variable), and as a side effect, defines an entry in an array that stores the two parameter values in an object. This would let someone write something like this as a keymap entry:

```auto
QK(Key_A, Key_LeftControl)

```

…and which defines the appropriate object in the Qukeys array as a side effect. I just don’t know if this is possible in C++ (and I don’t currently have access to a machine that can test this out).

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [December 22, 2017, 9:01pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/2 "2017-12-22T21:01:46Z")

</div>

It is possible to place function pointers in data structures. It is not possible to do so on the keymap, because pointers are 16bit wide, and would take up the entire key, and you would not be able to distinguish a pointer from any other value.

You could do this, but then you’d have to make _all_ keys functions. That’s probably not the fastest thing…

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 22, 2017, 11:41pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/3 "2017-12-22T23:41:06Z")

</div>

I don’t think I made myself clear. What I would like to do, if possible, is _call_ a function to define a key at compile time, setting `Key.raw` for that entry to the return value of that function.

---

<div class="post-metadata">

**Author:** ![jesse](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jesse/32/361_2.png) [@jesse](https://community.keyboard.io/u/jesse)\
**Post date:** [December 23, 2017, 1:21am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/4 "2017-12-23T01:21:03Z")

</div>

> [@algernon](#):
>
> It is possible to place function pointers in data structures. It is not possible to do so on the keymap, because pointers are 16bit wide, and would take up the entire key, and you would not be able to distinguish a pointer from any other value.

Long term, I think it’s something that would be very, very powerful, if we can figure out a way to make it not hurt too badly.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 23, 2017, 1:48am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/5 "2017-12-23T01:48:15Z")

</div>

> [@jesse](#):
>
> Long term, I think it’s something that would be very, very powerful, if we can figure out a way to make it not hurt too badly.

It does sound like an interesting idea, but not especially different from Kaleidoscope-Macros, from a user point of view. It’s also not at all what I’m trying to ask about. I don’t want to store a function pointer in the keymap; I want to set the value of a keymap entry by calling a function at compile time, and set up other things with that function’s side effects. If that’s possible (I’m pessimistic about the compiler allowing it, though).

Long-term, I think it makes more sense to use a sketch-builder program to work around the limitations of the compiler, and to vastly improve the readability of the keymap configuration.

---

<div class="post-metadata">

**Author:** ![jesse](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jesse/32/361_2.png) [@jesse](https://community.keyboard.io/u/jesse)\
**Post date:** [December 23, 2017, 2:01am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/6 "2017-12-23T02:01:16Z")

</div>

> [@merlin](#):
>
> It does sound like an interesting idea, but not especially different from Kaleidoscope-Macros, from a user point of view. It’s also not at all what I’m trying to ask about. I don’t want to store a function pointer in the keymap; I want to set the value of a keymap entry by calling a function at compile time, and set up other things with that function’s side effects. If that’s possible (I’m pessimistic about the compiler allowing it, though).

If you’re willing to share, it’d be useful to understand your specific desired end behavior.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 23, 2017, 5:17am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/7 "2017-12-23T05:17:45Z")

</div>

In its current incarnation, Qukeys are configured outside the keymap, with a separate declaration, so (for example) the keymap entry might look like this:

```auto
Key_A

```

…and the qukey constructor is in a separate place:

```auto
Qukey(QWERTY, 2, 1, Key_LeftShift);

```

@algernon had the idea that we could use the DualUse declarations in the keymap as Qukeys, which would work, but would be more limited than the separate definition:

```auto
SFT_T(A)

```

I’m thinking of trying to put this in the keymap:

```auto
QK(Key_A, Key_LeftShift)

```

…or some abbreviated equivalent:

```auto
QK(A, LShift)

```

…where `QK()` is a macro that expands to some function call, such as:

```auto
#define QK(pri, alt) defineQukey(pri, alt)

```

That function would be defined earlier, like so:

```auto
Key defineQukey(Key pri, Key alt) {
  static byte i = 0;
  // create the entry in an external array
  qukeys[i] = Qukey(pri, alt);
  // mark the keymap entry as a qukey, with an indexed offset
  return (Key){ .raw = ranges::QK_FIRST + i++ };
}

```

Then I’m back to the problem of getting the size of the array correct in its declaration, but right now I’m just wondering if this is feasible. I wouldn’t use a static variable in the function, of course; that index would end up being the size of the array, so it would be a class variable instead, but I hope that conveys the idea.

It’s like the DualUse declarations in the keymap, but would allow for the full range of possible `Key` values for both the primary and alternate `Key`s. I’m interested in the question of whether or not this idea is feasible (I’d be surprised if I tried this example and it worked), setting aside the issue of getting the size of the static `qukeys[]` array correct for the moment. I’m not convinced that this is a _good_ solution to the problem (I’m pretty skeptical, myself) — I just want to know what’s possible at this point.

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [December 23, 2017, 6:17am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/8 "2017-12-23T06:17:10Z")

</div>

> [@merlin](#):
>
> What I would like to do, if possible, is call a function to define a key at compile time, setting Key.raw for that entry to the return value of that function.

Oh, my bad. Sorry for the misunderstanding! I do not know of a way to achieve running a custom function at compile time, though. Highly doubt it is possible, and definitely not with side effects.

> [@merlin](#):
>
> ```c++
> Key defineQukey(Key pri, Key alt) {
> static byte i = 0;
> // create the entry in an external array
> qukeys[i] = Qukey(pri, alt);
> // mark the keymap entry as a qukey, with an indexed offset
> return (Key){ .raw = ranges::QK_FIRST + i++ };
> }
> 
> ```

Yeah, that’s not possible in C++.

If we used a Lisp… if we had a Lisp that can create efficient AVR code, now that would be amazing. And with Lisp macros, you could do something like this.

---

<div class="post-metadata">

**Author:** ![noseglasses](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/noseglasses/32/429_2.png) [@noseglasses](https://community.keyboard.io/u/noseglasses)\
**Post date:** [December 23, 2017, 6:55am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/9 "2017-12-23T06:55:25Z")

</div>

`constexpr` functions can run at compile time, but C++11 does not allow them to have local static variables. It isn’t possible using a class either, even if it had `constexpr` methods, because a `constexpr` object cannot be altered after construction.

---

<div class="post-metadata">

**Author:** ![noseglasses](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/noseglasses/32/429_2.png) [@noseglasses](https://community.keyboard.io/u/noseglasses)\
**Post date:** [December 23, 2017, 7:23am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/10 "2017-12-23T07:23:26Z")

</div>

> [@algernon](#):
>
> It is possible to place function pointers in data structures. It is not possible to do so on the keymap, because pointers are 16bit wide, and would take up the entire key, and you would not be able to distinguish a pointer from any other value.

This idea must be handled with care. Even if it wasn’t a problem of distinction for `Key`s, it would be definitely non-portable. It would e.g. already break Kaleidoscope-Hardware-Virtual as this would require storing a 32/64 bit address in a 16 bit integer ☠

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 23, 2017, 1:19pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/11 "2017-12-23T13:19:17Z")

</div>

Thanks, everyone. I expected as much.

> [@noseglasses](#):
>
> `constexpr` functions can run at compile time, but C++11 does not allow them to have local static variables.

I doubt this would change anything, but what if it was a plain global variable?

---

<div class="post-metadata">

**Author:** ![noseglasses](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/noseglasses/32/429_2.png) [@noseglasses](https://community.keyboard.io/u/noseglasses)\
**Post date:** [December 23, 2017, 4:19pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/12 "2017-12-23T16:19:22Z")

</div>

> [@noseglasses](#):
>
> because a constexpr object cannot be altered after construction.

This can be generalized to any constexpr intrinsic or objects variables except for local variables of constexpr functions. Also to global constexpr variables of any type. I am afraid, the answer is no.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 23, 2017, 4:21pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/13 "2017-12-23T16:21:50Z")

</div>

What about a non-`constexpr` global variable?

---

<div class="post-metadata">

**Author:** ![noseglasses](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/noseglasses/32/429_2.png) [@noseglasses](https://community.keyboard.io/u/noseglasses)\
**Post date:** [December 23, 2017, 5:02pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/14 "2017-12-23T17:02:13Z")

</div>

> [@merlin](#):
>
> What about a non-constexpr global variable?

Not accessible at compiletime.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 23, 2017, 5:29pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/15 "2017-12-23T17:29:09Z")

</div>

I’ll just have to write a sketch builder, then. There’s so much that’s known at compile time (or before) that C++ doesn’t provide any way to set…

---

<div class="post-metadata">

**Author:** ![noseglasses](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/noseglasses/32/429_2.png) [@noseglasses](https://community.keyboard.io/u/noseglasses)\
**Post date:** [December 23, 2017, 6:08pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/16 "2017-12-23T18:08:58Z")

</div>

I know how you feel. I were at this point a hundred times before. Wishing that the C++ pre-processor was a proper programming language that would enable global stateful variables at compiletime.

---

<div class="post-metadata">

**Author:** ![arthurvl](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/arthurvl/32/157_2.png) [@arthurvl](https://community.keyboard.io/u/arthurvl)\
**Post date:** [December 29, 2017, 9:08am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/17 "2017-12-29T09:08:07Z")

</div>

Hm. Call me crazy, but isn’t the template metaprogramming language of C++ turing-capable? That might allow solving the conundrum, by having e.g. QK\<Key\_LeftShift\>(Key\_A) as syntax, but it’d require representing all keys at the type level as wel. Not the prettiest solution, I admit 😉

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [December 29, 2017, 9:18am UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/18 "2017-12-29T09:18:50Z")

</div>

> [@arthurvl](#):
>
> Call me crazy, but isn’t the template metaprogramming language of C++ turing-capable?

😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱

I think that adequately expresses my feelings. 😉

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 29, 2017, 1:47pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/19 "2017-12-29T13:47:32Z")

</div>

TMP is absolutely _not_ the solution to this problem. Python & Perl are also Turing-complete, and in those languages, it’s actually possible to write comprehensible code that could generate a sketch file (or the sections of it that would be necessary to make the keymap more readable, anyway).

---

<div class="post-metadata">

**Author:** ![noseglasses](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/noseglasses/32/429_2.png) [@noseglasses](https://community.keyboard.io/u/noseglasses)\
**Post date:** [December 29, 2017, 5:36pm UTC](https://community.keyboard.io/t/function-calls-in-keymap-definition/897/20 "2017-12-29T17:36:53Z")

</div>

The turing machine is also turing complete, and much more simple than TMP. Why not… 🤪

All jokes asside. It would be fairly simple to code the keymap as A std::tuple template type. But that does not make the information available in other compilation units. It would require to define the keymap in a header file and include it in all places where the information would be required. But this helps only at compile time. There are no types at runtime! The information would need to be mapped to bits and bytes to be available at runtime…say, an array, and there we are back again.

There would yet be some benefit in such a solution. Different entries in the keymap could have different bitness and @merlin could easily store his qukey function pointer.

[Next page](https://community.keyboard.io/t/function-calls-in-keymap-definition/897.md?page=2)
