It struck me that it would be nice to have some form of ByteString in JavaScript utilizing TextEncoder
but instead of having some fancy newing up and going through a couple of hoops to make something that couldn't be handled like a string anymore what if a user could just do this.
b`hello world`;
And here is what the idea is based on, Rust's byte string.
b"hello rustations";
The JavaScript version would take on the form of a tagged function for a template literal, that's cool in itself, it never occurred to me that we could make such psudo primitive types. Okay what would the Byte string return? In theory it should return a Uint8Array of unicode utf8 encoded bytes, this is all doable so far. But what if I want to concatinate them?
JavaScript doesn't officially offer the ability to change what +
does, but a couple of languages do, this is known as operator overloading, changing an oporators behaviour on a type that you own. Therefore if I want to do:
b`hello` + b`world` // TypedArray + TypedArray 😵
Unfortunately though this is possible it does mean that I must provide the return value as part of an API, remember the result of this string notation is Not a string, it's a Uint8Array, you cannot add 2 TypedArrays together, so the API version could be kind of useful, a bunch of methods on my type would make it feel just a bit more native.
Here's how it's done:
function b(str) {
const _value = str[0];
return {
_value,
toUtf8Bytes() {
return new TextEncoder().encode(_value)
},
valueOf() {
// When the interpreter asks for the value of this object we give it the original string.
return _value;
}
}
}
The valueOf
overides the method used by the interpreter to compute and display values in Console etc etc, as far as JavaScript is concerned, this is a regular string, Meaning that any time I do use any operator, the valueOf
will be called like a setter getter. In my example in fact it's like I'm adding 2 objects together but tricking the interpreter into thinking it's a string. Don't worry if this is safe, everything is an object in JavaScript anyway it's not that wierd. What would work even better would be a es6 class instance of ByteString extending String, Anyway I found this absolutely fascinating and could be an incredible technique, I hope you did learn something too.
But why?
Post note, you can use interpolation syntax with this (with some modifications as to how you put the pieces back together) and pass this to webgl or Wasm really easily.
If byte strings are not your thing, what about a Vector class instance you could just add together or an abstraction of the CSSOM units, I can think of a lot of cool uses for this ahem hack.
Top comments (15)
I wonder if it still work for vector operation 🤔
I thought about it again, I remember the problem with vector 3 or vector 4 sizes, you need to retain all 4 or 3 values and represent them as a type in such a way that the plus can be used, eg string and number, and then re translate them back to vectors again, it sounds like a fun challenge, let me know if you try it
It has been a long time but I think I have a vector implementation
How do you detect what kind operation it is (e.g
+
,*
) by just listening onvalueOf()
?Here we go, the very technical details
2ality.com/2011/12/fake-operator-o...
Details of that are here 2ality.com/2011/12/fake-operator-o...
Unfortunately that technique is bound to fail when each expressions executed asynchronously. I think there is need a way to mark or even better get the value of the right hand side of the operator 🤔
I'm afraid at that point in the article, I reached my limit of comprehension, my attention span crumbled into little pieces of biscuits 😎. I did stumble across a method using Proxy, I know the reality breaking power of Proxy, so I suspect it may be the way to go. If you try to solve this one, I would like to see the results. But I can tell you that NPM does have this problem solved in the form of a few packages, some compiling and some runtime, best of luck my friend
At least it doesn't do any string operation. Another approach is to use either tagged-template-literal or JSX but it hit perf quite bad since it need to translate math ops that is in string into the real one (e.g
"+"
->+
). This is a big no for gamedev. The solution is to use babel-macro but it slow down the devserver since it depend on babel. I wish esbuild support macro or there is a go esbuild-plugin for this.Sorry for the rambling. Best luck to us 😃
You wrote
Oporator
instead ofOperator
.Dyslexia, so I meant whatever 😁
Oporator it's really nice, I will call oporator to all my tests of this kind of weirdo programming. Ty for inspiring me xD
You are most welcome 🤪
You might enjoy this, then:
reperiendi.wordpress.com/2020/08/3...
ooooooh!