2014-04-13

Bison

Today I decided to bite something of Bison. In my far past I had already experimented (though in a strong yacc fashion) with it, and by this I mean I have read few quick and simple tutorials — nothing more than the omnipresent infix calculator with frills, which by the way is also the main example in the manual, with enhancements found in mfcalc (hopefully updated for the future). To me the matter (using the tool as well as understanding bits of its inner working) is vast, deep and really interesting, but this is also the reason why I was always pushed towards stack-based languages in my experimenting with this world. Stack-based languages can polish complexity, largely undesidered in toy languages. But in the very same time it makes these toy languages almost alien. Stack-based or not, beyond a point a computer language can't miss a tool like Bison, unless you want to make a lot of craft work by yourself — there could be good reasons to do so, but I can't imagine one that fits the world of a toy language.

So, maybe only to make a noise and a vibration here and there, here's the result and, ladies and gentlemen, it is … hold on tight … the omnipresent basic infix calculator! More or less. In fact, you can assign the result of an expression to a symbol, and use it later. The lexical scanner reads only from standard input, and … again hold on tight … you can write 0.5a instead of 0.5*a! I admit it, MetaFONT book was very influential over me, and so it was the MetaFONT language, which is by heart the only language I know that accepts a more natural notation for the multiplication. Think about it: 2a is a syntactic error in the vast majority of computer programming languages, at least among the most known. Even languages thought to handle math stuffs, I am thinking about R and Octave mainly (and also Maxima!), disallow this syntactic sugar. Nothing bad, but my very simply infix calculator makes it possible! This is an incredible feature!! (Irony here, of course).

If you are interested in these basic things for beginners and in a complete, messed up, but working example to play on, you can take it from a gist of mine. I have avoided full C++ style (other examples show the “driver class” C++ approach), just used C++ where it turns to be ease (STL map class, since for the rest C would have sufficed). The next idea will be similar, maybe, and it will be about lambda. Indeed, since easter is near, I have started these tests in order to build a toy tool to play with the Church lambda calculus (shame on you, it already exists cool Xyz you can use very profitably! Ok, that's not my plan to be profitable or whatever, I am just playing to keep my last two survivor neurons almost alive), but I suppose I will be late, as usual.

Final note: on gist, if you assign the name for the file, you can't use the highlight you want. So, since .yy is an unknown extension, it made me impossible to select C++ highlight. We live in a world dominated by extensions rather than by users' will.

2014-02-22

Plans for Golfrun

The C Golfrun interpreter is stuck, as it was before. I think there's no reason to keep the idea of a full formalization of the language. I still want to rewrite it in C++11, but I don't want to find myself trying to inflate this or that feature of the language for the sake of it. Rather, I will use bits of C++11 when and if they fit; otherwise, plain C++, and even not too much C++ized i.e., it will be C++ for the STL, rather than for heavy Object Orientation; likely STL will be just a cozy replacement for the glib, and that'll be all.

In the meantime the language drifted and diverged from GolfScript in my mind. And from current Golfrun too! The changes I thought about were
  • no comments: code golfing can lack comments; and if you need them, a string that then you will drop from the stack can be used instead. There's a difference of course, since the string is digested at the lexical analyzer level while a comment is consumed by the parser and never results in a token. In contrast with a common good practice, the rule is: avoid comments! The change makes the symbol # available for other magic;
  • strings: use only "; strings without escape characters interpretation can be added through another syntax, like _"string". Another symbol, ', will be available;
  • case unsensitive symbols: case change can be used to separate symbols; e.g. thisIS has two tokens, THIS and IS. It could be useful to save some extra space.  A sequence like ThIs will produce 4 tokes: T, H, I, S.
  • maybe, rational numbers: a syntax like 0r13/3 could be used. A number like 0.123 would be written as 0r123/100, which has length 9 against 5. Cumbersome, and bad for code golfing in few strokes. Maybe I should accept the fact that a new symbol must be exploited for this; e.g. 0'123. No, I don't want to make it impossible to duplicate a number without adding extra space(s), e.g. 12.13++ must leave 37 on stack and not give a stack underflow instead. So maybe the dup must become ' and the dot must be back to its common meaning as part of syntax for numbers.
    • Rather the ' could be used as part of the syntax to introduce some kind of literals, e.g. '0.123 (where the dot is the decimal separator)
  • underscore can't be part of a symbol anymore, so hey_ and _hey will result both in two symbol tokens. But if followed by a number, it will be the unary minus, as in J; so you can write 5_5+ instead of 5 -5+ and the minus will be only a dyadic operator.
  • assignment syntax can't be used to assign to single character non-alphabetic symbols, e.g. {5}:* won't work. Instead, the syntax could be used to mean some sort of symbol modifier, i.e. interpreted as the token :*. The longer assignment syntax will be used (to be defined; it will be similar to the lookup system service) 
Other syntax changes were already made, in particular those allowing to feed the stack with complex numbers and to write the colon symbol (simply doubling it). Data types are or will be:
  • numbers
    • integers (arbitrary precision using the GNU Multiprecision arithmetic library)
    • complex integers, i.e. there's a real (integer) part and an imaginary (integer) part
    • rationals (complex or not), maybe
  • strings (of bytes; not C strings, so that they can contain zero bytes as well)
  • blocks, they are strings after all, but with a different syntax and can trigger different behaviour of operators
  • arrays (collection of eterogeneous objects)
  • hashmaps (keys are only strings; these strings can be the string representation of an object)
There will be 2 stacks: operands stack, and context stack. The context stack "contains" the operands stack and the symbol table. Currently, Golfrun can restore the original symbol table using a specific “system service”. This won't be needed anymore and the mechanisms of the context can be used instead. The context provides basically local variables capabilities and local stack capabilities.

Some extra built-ins will be kept, e.g.
  • dd (as 2dup in Forth); shorter synonym: D
  • sys (“system service”); single symbol ":" (written :: in the syntax) as synonym
  • stack (debug purpose mainly: dump the stack => stack associated with the topmost context)
  • sqrt (now it could return rational numbers approximating the result); shorter synonym: ST.
  • type (return the type of the object on the stack, without dropping it; shorter synonym: T
Others, added: e.g. 2swap (Forth) as SS, and rotation of more than 3 objects (@), as R.

A lot of symbols are now "free", and others need to have a defined behaviour with some kind of arguments. Coercion/implicit conversions need a clear, easy to remember rule.

An example of unclear behaviour is: [97 98]""+1/ will result in an array with two single character strings, "a" and "b". How do you go back? Something more elaborated as {(\;}%. This means that ( (or )) over a string will behave as if the string is an array of integers, except that the "head" (or "tail") is pushed as such, while the string remains a string. This is the same in GolfScript, where "ab") will result in two objects on stack, the string "a" and the integer 98. To get the "head" or the "tail" as single character, we need some extra work. In the eye of some operators, a string is an array of integers. Which is not wrong, but sometimes the information of the original interepretation is lost and coercion makes sense only if I am going to sum it with an integer. Something like Erlang $a could be desiderable (not using $  but something else instead).

Ok, I think it's time I start to code, without needing to have all this already planned in details, otherwise I won't start it again anymore.

2013-12-31

Am I a human?

Indeed, sometimes I have doubts about it.

Anyway, Happy New 2014.

2013-10-03

Github. A note

I had (and now I have again) a github account. My intention was to move Golfrun C++11 implementation there, but indeed I've never started it, nor I've finished plain C implementation, which is a mess. I had used only the gist, and there's a couple of articles here linking to gists. But they disappeared, I suppose since my account was “dormient”. Now I have created it again, but those gists are gone. I think I should rewrite them, but I am too lazy these days (months? years?). A lesson: figure if you can trust (free) clouds. I am joking, of course.

Edit

Indeed, gists are back, but now they think I am not a human… I think I'll be human again in 2014.

2013-09-29

Debian Wheezy, GNOME 3 and others small things


When my Ubuntu GNU/Linux distro received the "alert" that it wasn't supported anymore and the upgrade failed, instead of finding out why, first I tried to transform the distro into a LTS one (not totally successful because I had to downgrade too many packages), then I decided to compile what I "needed"; but my final thought is that it is not a good idea mixing automatically installed packages and packages compiled by you (out of the APT world), especially if you begin updating libs which many other programs rely on, or if you compile the last version of a program that needs the last version of a "core" lib. To make it short, the system started to behave inconsistently (maybe since I circumvented some dependency…). Time for a brand new installation.

2013-09-07

Pick a framework

I am paying for a website I do not update since I started paying for it. The reason why I decided to purchase the domain and the web space was that another site was gently hosting some content of mine, but that site was going to go down soon (and in fact, currently is). So I needed some room for my old content, but I also wanted to do something modern, maybe cool, to experiment with several technologies (?). Thus, instead of copy-pasting my old site into the new space, I decided to carve my own custom CMS from scratch. It soon turned out to be a task beyond the quantity of my spare time, and my ability and my will too. I lost interest in it and in the same time decided to wait before to put the old content back, soon I will pick some cooked CMS or alike and inflate the old contents in it, I was saying to myself. But that "soon" became years. Since 2011 my site is simply dead (and it exists since 2011…!). Maybe like me (don't you hear my cavernous voice?)

I have renewed the fee until 2014, therefore I have to do something with it before that endline. If the aim is to host contents online, then creating a custom CMS is totally worthless. I like the idea that if the content of a site is great, then you don't need too much lights and fireworks, since people land on your site searching for the content you provide, and they end to be caught by it, despite of what it looks like — and of course I am not chasing the fame. I agree with this simple idea: a website is about its contents. It could be made even by plain HTML, for the sake of its hypertextual power, and be successful among the target niche (i.e. the two or three persons interested in that content). I am thinking about a site like Fravia's. But if I look to my own content, I see poor things. This blog contains cheap tech posts, simple sillyness, pointless speechs, and other few stuffs that hardly are worth a reading, like this very same post. This is supposed to be a "tech blog" about mainly computer related topics, but it is no more than "curiousity material for computer unsavvy". Moreover my research (I dare to call it so) flow is dried since at least 1 year. I am like a surfer surfing on a wave, a moment it's up, then you slip, gaining speed, and at last you are down waiting for the next wave. But each wave has its own peculiarities. The wave I am (more or less satisfactorily) surfing now is more about literature and politics, even if there are some hook in the computer world — but it's just because their are powerful tools you can use for several aims. The fact is, I am not using my spare time to program (though I do it, say, 8h/day, 5 days per week) as I did before. This is going to change, soon, or maybe later, the problem is exactly when, I say tomorrow, then I wake up and realize a whole year has flied away, and there's dust on several project, and on knowledge too, and on partners too, and on languages I was learning like Erlang. Currently, as said, I am more on other interests, but something started to seethe underneath. It begins with idea like the following: let's pick a framework and put anything on the site.

It seems a simple idea, but as usual I put my goals too far from where I am now, likely overstimating my current skills and the amount of spare time I am willing to consume for those goals.

Instead of creating something from scratch, the idea is to practice a framework like CakePHP. I picked it since it was the one I already knew a bit someway, but not enough. But the drift is lurking, and I am very prone to it, I am always drifting someway. The clear, fast, almost near goal to use CakePHP to develop something to give life to my site was going a little bit further. It starts with asking few questions, but the most important is: what kind of content do you want for your site? For my old content I don't need more than a directory listing, and something like a wiki or a blog, but for these I've chosen third party places like blogspot. So, I can't focus on the old content. The reason why I need a lights-and-fireworks site is indeed that my content sucks: i.e. nobody can be interested in it spontaneously. I have to add some spice, some seasoning, tasty sauces, to avoid people run away. Or rather I stick to simple directory listing, which works for so-called "nerds" and content-searcher. It'd be easy. But also boring to me. 

At first I had maybe just a problem: what kind of web application I need in order to present my old contents and likely to be able to add new one easily and swiftly? This is a great problem: saying I want to develop something is greatly silly: it seems the aim is not clear. And in fact, it is so! So I have to take a pencil and a paper, or other tools on the computer, and sketch the site, I know the contents I have, I need to imagine how I want to show them. Do I need just a showcase? I can add things later, maybe in the 2023, when a bloody world war (maybe nuclear) will be in progress, and I will be biologically dead. Questions that need to be answered, not necessarily in the order I write them:
  • What kind of content will you put on your site? I could be interested in many things, though how much time I spend on them depends on the wave,  and there are waves that haven't risen yet.
    • Graphic creations
      • 3D (Blender, POV-Ray, etc.)
      • 2D (GIMP, gfx tablet,  photos, generated by computer programs/simulations or drew by hand, etc.)
      • vector gfx (SVG, PostScript, Metafont/Post)
      • short films (link to youtube channel), in fieri
    • Music/noise creation
      • MIDI (composition, algorithmic composition etc.)
      • samples (Csound, etc.)
      • songs (likely link to other hosting sites)
      • articles about processes about "music" (another blog?)
    • Programming and computer related topics
      • desk/laptop (Amiga, GNU/Linux, ...etc.)
      • mobile (Android, Java, etc.)
      • articles (this blog?)
    • Writings (PDF + LaTeX/TeX / wiki content?)
      • Essays, lessons, articles, papers, slides (wide range topics)
      • Tales, novels, scripts
      • blogs (this one, the others, new one?)
    • Link collection / social
      • Linking with "streams" from social network like Diaspora, Twitter, Pump.io or alike
      • Linking with articles on external blogs
      • Bookmarks (delicious?)
      • links to github, sourceforge, bitbucket, wherever I have something hosted (few things, mostly crap)
    • Experimenting with web apps and services
      • social networks
      • rendezvous-point (f2f apps?) 
    • Advertising myself
      • who am I? what I do? what I've done?
  • What kind of technology do you want to use?
    • Currently I am bound to PHP+MySQL serverside. I don't want to make something that works on every browser, so I can stay on the edge of HTML5/CSS3 and Javascript without problems.
      • RAD PHP frameworks (which paradigm? MVC...?)
        • CakePHP?
        • Yii?
        • Symfony?
        • Others?
  • How do you think to show the contents? Can the user add their own? (No, but I'd like to experiment with OAuth and allow limited controlled access to some service, but I don't know which, clear, isn't it?)
    • No idea.
I thought to have found the right one in CakePHP, but then I've seen how many other there are out there, some are maybe "smaller", and therefore they can fit my need better. Or maybe not,... but there would be always time to add another framework in another dir!

Ok, now it's clear I should be studying CakePHP and planning the app in details (and in surface, I am going for the minimalism), instead of writing too many words like these. And my Android device is even waiting for some fresh original bytes to bite from me. It must wait. O and I have admit that such posts comes to life just to remember me that this blog exists! (While I am feeding the italian side blog, with a lot of posts, not technical one of course).

P.S. Forgot the only maybe meaningful part: the problem with RAD tools is that they are Rapid only if you know them, so, let us suppose, they will be Rapid the second time you develop using them; otherwise, they are not rapid. But how fast you can learn them, how steep is the learning curve? This may affect the choice. I started with CakePHP, but now I consider interesting Yii, but which one fits better my need? And so on, in a circular trip!

2013-04-24

Just another thought about how patent can be silly

Occasionally (sometimes often, sometimes rarely) I try to do my best to answer some question on stackoverflow.

Recently I have answered this question but at first I had interpreted badly the OP request: in fact my first proposed solution told him to use grep to eliminate the lines containing final asterisk. But the user wanted the asterisk to be ignored, not the line to be deleted. So I fixed my answer to use sed to delete the asterisk and let diff make its work.

The edit has timestamp 2013-04-23 13:28:19Z.

Soon after I posted it, I saw another answer which proposed the same "double pipe" solution I gave but with the correct sed. Its timestamp was 2013-04-23 13:28:50Z, i.e. it came after the fix of my answer; in the same time it cites my previous wrong answer, so it was "built" on the shoulder of it (the one with the grep instead of sed).

That was interesting and made me think about a reason to be strongly against some kind of usage of patents (and maybe the whole patent industry), and how these can stop indeed independent innovation and ideas. Patent advocates state exactly the opposite, but it's of course a matter of defending their interests (and/or protegees)... a matter of money and not of innovation, progress, expanding human knowledge and so on.

The point is this: we proposed the right sed-solution independently. (He credited me just for the structure of the command line, i.e. the way the sed command is invoked in order to obtain the diff). Saying it differently, the functional part of the answer (the sed trick) was "produced" independently by each others.

This shows that having the same problem to be solved, having similar knowledges, similar shared informations and similar set of tools can make two minds to propose solutions that are similar if not identical.

That's why patents to "protect" intellectual properties are a very dangerous lie and stop innovation, giving the key to it in the hand of "who came first" in order to make money, prohibiting other minds to arrive to similar solutions independently.

The simpler is the "object" of the patent, the higher the probability two or more people produce the same solution. So that allowing patents can prevent others from using shared, common, widely available human knowledge to reach any result, lock the consumers of a solution to one solution provider (for a long time) and so promote differences, cutting the less rich out from the game and make it possible price control to maximize earning despite the intrinsic value of the "object" (when applicable), in detriment of the consumers.

2013-04-19

Against the misuse of word-processors

I should never be tired of repeating it: word-processors are one of the more overrated and misused software in the computers of too many common users.

It's not a battle against the infamous Microsoft Word, even if from the freedom point of view, office suite like OpenOffice or LibreOffice are a better choice. The speech holds for these software as well: the problem is with that kind of software, with what is called currently word-processing.

In short the main point is that textual, human readable formats in specific contexts are better than any binary format. It should be not hard to agree when the content is itself textual: an article, our next best-seller book, our thesis about political science, our screenplay, notes of several kind (shopping list, names and numbers you need to remember), a blog entry and so on. They all are primarily made of text.

Unfortunately people are accustomed to WYSIWYG, which is often evil unless you are an artist and you are doing some kind of visual elaboration of the text which is part of the message you want to convey, or if you have to arrange the text altogether with a lot of graphics. Users should emancipate from this visual approach and learn to focus on the content, when it is what they have to deal with.

Word-processors make users to believe they are in control of how things will be presented and that it is their responsibility. But often it's not their duty. Often it's someone else duty and the users must focus on the content and the role of segments of this content: they have to mark a piece of text e.g. as chapter title, but forget about how that chapter title will be rendered.

Often the way things must be presented is codified; there are rules describing page size, font styles, font sizes, spacings and so on. Once you get that you need to deal for real only with the meaning or role of the things you write, then you are ready to throw away your preferred word-processor (or use it in a totally different way — modern WP would make it possible, but they don't work as well as other tools).

So you must prefer human readable formats: the file containing the text you wrote does not need a specific piece of software. It's enough a text editor. You can use a language that allows you to describe the actual content, marking it someway. And that's the sense of a markup language.

When I talk about human readable formats and markup language I am not thinking about several eXtensible Markup Languages produced and consumed by a machine: in fact even the evil Microsoft new MS Office formats, altogether with the OpenDocument standard for documents (the standard you should use when you won't follow the suggestions of this article), are XML based formats. So you could read the contents, but unlikely you can benefit of this possibility, and it would be even harder if not impossible to write that content by hand. Moreover everything is packaged into a zip archive and so those formats appear as binary.

Some reason why purely textual, simple formats are better than binary or complex textual machine-addressed formats:

  • contents can be understood having no or few knowledge of the format (this does not mean it's easy or they are usable the same way you would do interpreting correctly and knowing the format);
  • script to parse the data can be easily written by a programming enabled mind. Although the finest art is not for everyone, simply grepping or data extraction should be, almost;
  • the only program needed to view or edit the file is a text editor: an application that must be on every computer with any operating system installed. The data are operating system independent and software independent (not 100% true, but it is in common modern computing worlds);
  • merging and splitting can be done easily; if there's some sort of structure, this minimal knowledge is required in order to let the splitted files or the single merged file to keep an independent meaning;
  • diff-ing and comparing can be done with standard common tools;
  • versioning tool can track changes more easily (without relying on the specific tools of the specific software that can handle the binary format)

Simple markup languages are particularly tailored for benefitting of these features. This article was written using a subset of HTML, the markup language of the World Wide Web, and stored into a directory managed by Mercurial, a distributed Source Control Management tool, that makes it possible to track the changes and the history and (pushing to and pulling from a remote server) I could also contribute with myself. Without using a special software to handle this particular format.

The format of course was chosen according to a specific need: in this specific example the format is suitable for direct web publishing. Other requirements would have made us choose other formats. E.g. since I am an Emacs user, the format I choose for notes and other casual writings is often the org-mode.

Interpreting the markup language (that could be easy and at hand for a lot of computer geeks) it is possible to transform it (to another markup language or to anything else) and elaborate it in several mechanical ways.

Another classic example is when you think about stuffs you want to see printed, like for example a book, or an article on paper; then one of the most suitable format is LaTeX.

Even if you need a specific application (a set of applications and data, indeed) in order to produce the final document ready to be printed (e.g. a PDF), the format is textual, structured, it was thought to be written by hand (with just a text editor) and focus on content and not on presentation. From one unique source you can produce e.g. PostScript, PDF, HTML document or (virtually) any kind of document and format. And yet, you can read it with a text editor. And you can even add metainformations in disguise of comments.

For sure everything is clearer if you use a modern powerful text editor able to highlight the syntax of such languages. But it is not something you can't live without.

Once you learn to separate the meaning from the way it is presented, then you get the value of using everything but a word-processor for the vast majority of the things you may imagine (when the value is the content and not the way it is shown).

Said it in another way: the WYSIWYG approach is largely overrated. You must learn to separate the actual content from the way you want it to be seen on a screen, paper or other media. Learn that a lot of these way are codified (or they should), and usually you are not the one who codified it. So, you must focus on content, since the description of how to show it sits elsewhere — maybe it's even someone else duty, thus you have not to worry about.

Finally: before to fire a word-processor, consider other approaches that can make your life easier, even if it doesn't seem so at first (in this article I have ignored several anecdotes that drove crazy a lot of word-processors' users trying to obtain what they wanted from their software, losing more time on these efforts than in producing their content). In general, if you drop all word-processors forcibly, you will discover how rarely useful they are and how beneficial other workflow can be.

2012-11-25

Compressing

Sometimes I have to compress-archive files which differ not too much. I can see it with a glance, but computers have nothing similar to human vision... The archive formats I consider are zip (only if I have to share with windowsers who could be scared by other formats), tar.gz (tgz), tar.bz2 and if I don't care about file attributes, 7z. Among these, 7z compresses usually the most.
But since the files I am archiving have very repetitive pattern, I am not satisfied with the result of all archivers (except maybe 7z...).
Could we obtain better results in some way?

First, I have generated two files. They are the same file except for a byte in a certain position.

15274 file1.txt
15274 file2.txt


Then I have archived them:

 1847 files.7z
 3363 files.rar
 7142 files.tar.bz2
 7918 files.tar.gz
15342 files.zip


I have added rar too for the sake of completeness. Zip compresses each file at 50% more or less, so the final archive size is more or less half the size of the two files altogether. The others perform better, and 7z is simply the best. (The content of the file is important of course: it contains the number from 0 to 4095 written in ASCII without spaces or newlines: few symbols, repetitive patterns, no random).

Could it be better if I store just the first file and then a diff file? The result is:

1833 files.7z
1803 files.rar
5180 files.tar.bz2
7776 files.tar.gz
7891 files.zip


Zip reaches the performance of tar.gz (we could say it keeps making the first file half, while the diff file is small and so does not contribute too much to the final size). Rar seems slightly better than 7z (but the difference is negligible), and 7z itself does not gain too much from this pre-processing: it almost seems it is the only one that implements an algorithm able to crash the repetitions. Tar.gz's gain is small, tar.bz2 is bigger but not yet enough to keep the pace with 7z.
(Small differences could be due also to the file name of the diff file, which is "file1.txt.file2.patch"; 7z and rar do not store the filenames in clear, zip does, tar surely write filenames in clear, but of course bz2 and gzip compress them too).

Now let's try with two 16k (exactly 16*1024=16384 bytes) files containing the same random bytes (no special care in the random distribution), except for 1 bytes which differs in file2. The results:

16838 files.7z
32971 files.rar
20904 files.tar.bz2
16796 files.tar.gz
33086 files.zip


Zip stores the files. Rar is a little bit better, but not enough. Interestingly, gzip beats everyone, and 7z is a bit behind. Anyway, it seems like 7z and tar.gz algorithm exploits differences between files (since gzip works at a level where it is not aware of distinct files, it means it "explores" the stream and recognizes repetition patterns? better than bzip2? this need further analysis...). If I store only the first file and the diff file, I obtain

16824 files.7z
16606 files.rar
17114 files.tar.bz2
16654 files.tar.gz
16765 files.zip


Now almost all the archivers-compressors obtain the "same" result. Strangely, tar.bz2 gain is the worst. Rar, tar.gz and zip wins over 7z!

No conclusions. The way I have obtained the diff file is:

diff <(xxd -c 1 file1.rand) <(xxd -c 1 file2.rand) >file1.rand.file2.patch

and similar for the no-(pseudo)random case. Btw this could be not the best way, but indeed it's not important for this argument.