From 58adddcd74469f403abe8d79734bb15215520c4e Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Tue, 10 May 2016 20:52:14 +0200 Subject: Fix disconcerting usages of `it's` instead of `its` --- ..._using_scheme_as_a_metaphor_for_template_metaprogramming.md | 10 +++++----- articles/2015-09-18_nokia_heir_and_hardware_keyboards.md | 4 ++-- articles/2015-09-24_the_joys_of_ipv6.md | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'articles') diff --git a/articles/2015-03-06_using_scheme_as_a_metaphor_for_template_metaprogramming.md b/articles/2015-03-06_using_scheme_as_a_metaphor_for_template_metaprogramming.md index bd14983..8bd8f79 100644 --- a/articles/2015-03-06_using_scheme_as_a_metaphor_for_template_metaprogramming.md +++ b/articles/2015-03-06_using_scheme_as_a_metaphor_for_template_metaprogramming.md @@ -2,7 +2,7 @@ Back in January I looked at compile time computation in C++ based on handling lists in a _functional fashion_ using a mixture between templates, generic lambda expressions and `constexpr` functions. The conclusion of the [appropriate article] was that the inherent restrictions of the approach taken in [ConstList], namely the missing guarantee on compile time evaluation, inability to make return types depend on actual values and lambda expressions being unable to be declared as constant make viewing types as values and templates as functions the superior approach. This article describes how this approach works out in practice. -While [ConstList] turned out to be of limited use in actually performing compile time computations, it's list manipulation and query functionality was already inspired by how lists are handled in _LISP_ respectively its more minimalistic dialect _Scheme_, especially by the functionality described in the latter's [SRFI-1]. +While [ConstList] turned out to be of limited use in actually performing compile time computations, its list manipulation and query functionality was already inspired by how lists are handled in _LISP_ respectively its more minimalistic dialect _Scheme_, especially by the functionality described in the latter's [SRFI-1]. When I started developing a new library porting this basic concept to the _type as value and templates as functions_ approach called [TypeAsValue] it quickly turned out that a _Scheme_ like paradigm maps quite well to template metaprogramming. This was initially very surprising as I did not expect that C++ templates would actually feel like a - admittedly rather verbose - functional programming language if used in a certain way. ~~~ @@ -22,7 +22,7 @@ using sum = tav::Fold< ~~~ {:.language-cpp} -As we can see compile time computations expressed using this approach are more or less direct mappings of their _Scheme_ equivalent if we overlook the need to explicitly declare types, the different syntax used for defining bindings as well as it's immutability. +As we can see compile time computations expressed using this approach are more or less direct mappings of their _Scheme_ equivalent if we overlook the need to explicitly declare types, the different syntax used for defining bindings as well as its immutability. While [TypeAsValue] started out as a direct reimplementation of my previous attempt I am happy to say that the conclusions drawn concerning the superiority of a stricly template metaprogramming based implementation held true and enabled the implementation of equivalents for large parts of the _Scheme_ list library. This includes actual content dependent list manipulations such as [`tav::Filter`], which were impossible to implement in [ConstList], in addition to e.g. a compile time implementation of _Quick Sort_. @@ -119,7 +119,7 @@ struct fold_pair { ~~~ {:.language-cpp} -While the listing of `tav::detail::fold_pair` shows how the partial specialization of its [`tav::Pair`] parameter allows recursion until the list ends[^3], it also forces us to define it's actual type in terms of a public `type` member `typedef`. Such a member type definition can lead to cluttering the code with `typename` keywords which is why [TypeAsValue] employs a simple [`tav::Eval`] template alias to hide all `typename *::type` constructs. +While the listing of `tav::detail::fold_pair` shows how the partial specialization of its [`tav::Pair`] parameter allows recursion until the list ends[^3], it also forces us to define its actual type in terms of a public `type` member `typedef`. Such a member type definition can lead to cluttering the code with `typename` keywords which is why [TypeAsValue] employs a simple [`tav::Eval`] template alias to hide all `typename *::type` constructs. ~~~ template < @@ -131,7 +131,7 @@ using Fold = Eval>; ~~~ {:.language-cpp} -Hiding member type defintions behind template aliases enables most _higher_ functionality and applications built using it's functions to be written in a reasonably minimalistic - _Scheme_ like - fashion as we can see in e.g. the listing of [`tav::Every`]. This also explains why [`tav::Pair`] recursively defines it's own type, as we would otherwise have to be quite careful where to resolve it. +Hiding member type defintions behind template aliases enables most _higher_ functionality and applications built using its functions to be written in a reasonably minimalistic - _Scheme_ like - fashion as we can see in e.g. the listing of [`tav::Every`]. This also explains why [`tav::Pair`] recursively defines its own type, as we would otherwise have to be quite careful where to resolve it. ### Bindings @@ -216,7 +216,7 @@ Both of these examples are certainly not what [TypeAsValue] might be used for in ## Summary -While the _Scheme_ metaphor for template metaprogramming in C++ certainly has it's limits, especially in the area of anonymous functions, I think that this article as well as the actual implementation of [TypeAsValue] are proof that it holds up quite well in many circumstances. As stated in the introduction to this article I was very surprised how close template metaprogramming can feel to a _real_ functional programming language. +While the _Scheme_ metaphor for template metaprogramming in C++ certainly has its limits, especially in the area of anonymous functions, I think that this article as well as the actual implementation of [TypeAsValue] are proof that it holds up quite well in many circumstances. As stated in the introduction to this article I was very surprised how close template metaprogramming can feel to a _real_ functional programming language. All listings in this article as well as the [TypeAsValue] library itself are freely available under the terms of the MIT license on [Github] and [cgit]. Feel free to check them out and contribute - I am especially interested in practical solutions to providing better partial function application support or even full compile time lambda expressions that do not require the whole library to be designed around this concept. diff --git a/articles/2015-09-18_nokia_heir_and_hardware_keyboards.md b/articles/2015-09-18_nokia_heir_and_hardware_keyboards.md index b5368e6..93e77bd 100644 --- a/articles/2015-09-18_nokia_heir_and_hardware_keyboards.md +++ b/articles/2015-09-18_nokia_heir_and_hardware_keyboards.md @@ -9,11 +9,11 @@ While the _Jolla_ may have much faster hardware, a bigger screen, multipoint tou The first and foremost problem is of course the lack of hardware based user interfaces such as unlock sliders, camera protectors, buttons and of course hardware keyboards. While the latter is at least partially solved by the _TOHKBDv2_ external keyboard I helped fund last year and received two months ago it - like everything else concerning the user interface - is just not as good as what was already available as a complete package back in _2009_. To prevent misunderstandings: I am very grateful for the work _Dirk et. al._ did with [FunkyOtherHalf] to produce a usable external keyboard for the _Jolla_ in a very limited production run of only a few thousand devices. If you view it as what it is - a prototype - it actually exceeds all expections one could have reasonably had. -But sadly this does not change the reality that at least my other half keyboard is not consistently usable in a day to day fashion. The magnet based connection between the keyboard part an the backcover of the _Jolla_ is rather flaky and sometimes requires reconnects during usage. Furthermore some keys, in my case _U_ and _N_, don't work as well as the other keys which frequently disrupts the flow of typing. If you were to disregard these issues, the keyboard itself, especially the layout, would be better than the _N900_'s - sadly only in theory as it's slider mechanism and feel of use in practice is still superior. +But sadly this does not change the reality that at least my other half keyboard is not consistently usable in a day to day fashion. The magnet based connection between the keyboard part an the backcover of the _Jolla_ is rather flaky and sometimes requires reconnects during usage. Furthermore some keys, in my case _U_ and _N_, don't work as well as the other keys which frequently disrupts the flow of typing. If you were to disregard these issues, the keyboard itself, especially the layout, would be better than the _N900_'s - sadly only in theory as its slider mechanism and feel of use in practice is still superior. ![Jolla with TOHKBDv2](https://static.kummerlaender.eu/media/jolla.png) -Of course the _Jolla_ has it's strengths: _SailfishOS_ is a pleasure to use[^0] and the faster internals are essential to using it without having to wait on the device every other interaction. Also the replacement of _GTK_ with _Qt's QML_ as the primary _UI_ framework was definitly the right step and being able to execute _Android_ applications is useful for when there is no _SailfishOS_ counterpart. +Of course the _Jolla_ has its strengths: _SailfishOS_ is a pleasure to use[^0] and the faster internals are essential to using it without having to wait on the device every other interaction. Also the replacement of _GTK_ with _Qt's QML_ as the primary _UI_ framework was definitly the right step and being able to execute _Android_ applications is useful for when there is no _SailfishOS_ counterpart. But while slow the _N900_ is superior in other situations such as direct sunlight and precision usage using a stylus. The transreflective background of the display means that one can turn off the backlight completly if the sun is shining bright enough and use it as a source of light whereas the _Jolla_ display is often not readable in bright sunlight. While _SailfishOS_ is more fluid and looks nice, _Hildon_ with all transitions turned off feels quick in a way that an animated UI simply does not. Add to that the various unlock methods such as sliding out the keyboard, sliding back the camera protector or sliding the unlock button and the daily usage of the _N900_ feels more intutive and quicker than any touch based interface I've tried. This problem is increased by the recent _SailfishOS_ UI overhaul that replaces gestures with buttons in various parts of the interface. Many of the nice properties of _Jolla's_ interface such as sliding from the top of the display to lock and sliding up to access the application menu from the lockscreen now have to be patched back into the UI using custom repositories. Admittedly it is great that this is even possible without requiring deep changes to the system such as _jailbreaks_ as in other mobile systems. Furthermore with the right set of patches from the _Warehouse_ it is possible to e.g. enable nearly system wide landscape mode support which is very nice. diff --git a/articles/2015-09-24_the_joys_of_ipv6.md b/articles/2015-09-24_the_joys_of_ipv6.md index 47c2e0e..eb7c8ee 100644 --- a/articles/2015-09-24_the_joys_of_ipv6.md +++ b/articles/2015-09-24_the_joys_of_ipv6.md @@ -77,7 +77,7 @@ One disadvantage of _IPv6_ in comparison to _IPv4_ is that the addresses are not One possible solution for this is to build some kind of private _DNS_ that announces the _IPv6_ addresses of all my devices so they can more easily find each other. But before doing that I will first wait until the _SheevaPlug_ gets assigned a new _IPv6_ address by my provider - in the best case that will never happen. -There are some privacy concerns around this property of _IPv6_ as never changing addresses allow for even easier long-term tracking of individual Internet usage. These concerns are addressed by it's [privacy extensions]. While these extensions may be a good idea for devices used to consume the Internet[^6] I have disabled them on my dynamically addressed servers by setting `net.ipv6.conf.all.use_tempaddr` to zero. +There are some privacy concerns around this property of _IPv6_ as never changing addresses allow for even easier long-term tracking of individual Internet usage. These concerns are addressed by its [privacy extensions]. While these extensions may be a good idea for devices used to consume the Internet[^6] I have disabled them on my dynamically addressed servers by setting `net.ipv6.conf.all.use_tempaddr` to zero. [^0]: Previously called _KabelBW_ in southern Germany [^1]: I received the shipment confirmation and tracking code days after I had already received the package and _Unitymedia_ knew nothing about this. It seems they mixed up my package and sent it way to soon. -- cgit v1.2.3