Live data from Hacker News

Go-Restructure: Sane regular expressions with struct fields

github.com

21–30 of 47 posts

Re: Go-Restructure: Sane regular expressions with struct fields

#21
post #16

What's wrong with named capture groups ? http://www.regular-expressions.info/named.html

They're untyped and inconvenient to put back into a structure: you have to define the struct then a mapping function from regex matches to the struct. This takes care of the mapping through the struct you have to define, and provides somewhat clearer separation of the components (akin to using a VERBOSE flag in some regex engines).

Plus not all regex engines support named capture groups, JS's regex don't, and while Go's engine technically supports them it might as well not: you can't index into a match using that, you get a list of group names of size the total number of match groups, and the name at index i is the name of the i'th match group.

Re: Go-Restructure: Sane regular expressions with struct fields

#23
post #14

Here's a 1-1 port in JavaScript https://github.com/benjamingr/js-restructure function matcher(obj) { "use strict"; let props = Object.getOwnPropertyNames(obj); const re = new RegExp(props.reduce((p, c) => p + (c.startsWith("_") ? obj[c] : `(${obj[c]})`), "")); props = props.filter(x => !x.startsWith("_")); return function(pattern) { let o = {}; const res = re.exec(pattern); for(let i = 0; i And example usage: ```js m…

In js, are obj field names stable on insertion?

Normally I wouldn't expect getOwnPropertyNames to return them in the same order.

Re: Go-Restructure: Sane regular expressions with struct fields

#24
post #14

Here's a 1-1 port in JavaScript https://github.com/benjamingr/js-restructure function matcher(obj) { "use strict"; let props = Object.getOwnPropertyNames(obj); const re = new RegExp(props.reduce((p, c) => p + (c.startsWith("_") ? obj[c] : `(${obj[c]})`), "")); props = props.filter(x => !x.startsWith("_")); return function(pattern) { let o = {}; const res = re.exec(pattern); for(let i = 0; i And example usage: ```js m…

JavaScript doesn't guarantee the order of keys.

[edit] Also, the API makes less sense because JavaScript isn't statically typed so you can make up the result object on the fly.

    match('^(?\w+)@(?[^@]+)$', 'joe@example.com') => {'user': 'joe', 'host': 'example.com'}

Re: Go-Restructure: Sane regular expressions with struct fields

#25
post #23
post #14

Here's a 1-1 port in JavaScript https://github.com/benjamingr/js-restructure function matcher(obj) { "use strict"; let props = Object.getOwnPropertyNames(obj); const re = new RegExp(props.reduce((p, c) => p + (c.startsWith("_") ? obj[c] : `(${obj[c]})`), "")); props = props.filter(x => !x.startsWith("_")); return function(pattern) { let o = {}; const res = re.exec(pattern); for(let i = 0; i And example usage: ```js m…

In js, are obj field names stable on insertion? Normally I wouldn't expect getOwnPropertyNames to return them in the same order.

According to the spec, no guarantee of order is made. The latest spec even adds separate a Map object that does make that guarentee: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re: Go-Restructure: Sane regular expressions with struct fields

#26
post #14

Here's a 1-1 port in JavaScript https://github.com/benjamingr/js-restructure function matcher(obj) { "use strict"; let props = Object.getOwnPropertyNames(obj); const re = new RegExp(props.reduce((p, c) => p + (c.startsWith("_") ? obj[c] : `(${obj[c]})`), "")); props = props.filter(x => !x.startsWith("_")); return function(pattern) { let o = {}; const res = re.exec(pattern); for(let i = 0; i And example usage: ```js m…

JavaScript doesn't guarantee the order of keys. [edit] Also, the API makes less sense because JavaScript isn't statically typed so you can make up the result object on the fly. match('^(? \w+)@(? [^@]+)$', 'joe@example.com') => {'user': 'joe', 'host': 'example.com'}

Yes it does - it does for getOwnPropertyNames but not for Object.keys.

Re: Go-Restructure: Sane regular expressions with struct fields

#27
post #25
post #23

Earlier quoted context omitted.

In js, are obj field names stable on insertion? Normally I wouldn't expect getOwnPropertyNames to return them in the same order.

According to the spec, no guarantee of order is made. The latest spec even adds separate a Map object that does make that guarentee: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

the order is guaranteed. https://esdiscuss.org/topic/property-ordering-of-enumerate-g...

Re: Go-Restructure: Sane regular expressions with struct fields

#28
post #11

This depends on reflect. What's the speed penalty?

I came to the comments section to ask the same question. I've always liked the idea of reflection but avoided it because of performance scares (and usually I can solve the problem another way).

Since we're discussing the performance footprint of regular expression libraries, it's also worth mentioning how slow even just running the base regexp library can be. For example, the email example could also be written without regex:

    indices := strings.Split("joe@example.com", "@")
    fmt.Println("Name:", indices[0])
    fmt.Println("Domain:", indices[1])
( https://play.golang.org/p/ZezcoBjc9v )

Obviously the above code doesn't do any sanity checks - which is where regular expressions can often make things easier. But the above would run a lot faster than a regexp pattern match.

Re: Go-Restructure: Sane regular expressions with struct fields

#29
I recommend that the first example be changed to use struct{} as well. The "strings" are still present in the struct footprint if you leave them there: http://play.golang.org/p/ZG1ULgzSwZ And people luuuuuv to pick up the one example where you did something a bit wrong and copy paste like mad....

I'd really rather see something that generates marshaling code based on a regex or something, though. This loads an awful lot of meaning onto things that most code assumes doesn't have meaning, like struct field order. It looks really clever in isolation but if you start playing multiple tricks like this in one code base they'll start conflicting.

For example, note how you now can't use encoding/json on these objects as currently written. Now, that's fixable... well... it's probably fixable. AFAIK the struct tagging system isn't actually specified, so, for instance, if you try to put a tag

    regex:"[^\"]+",json:"quotefree"
there's no guarantee how anything will parse that. Should that backslash be there to get the "character class of everything but double-quote"? Will the regex code get the backslash? Will encoding/json see a field 'regex:"[^\"' and a field ']+",json:"quotefree"' and then fail because there's only a field named ']+",json' and not one named 'json'? Will you encounter one of those situations where the backslash is simultaneously required and not required? Beats me. Plus I don't guarantee stability on whatever the answer is between versions, nor do I guarantee it if you reverse the order of the two things, nor do I guarantee it if you try to add a third struct tag.

I would suggest taking this code and converting it into a function

    UnmarshalRegex(*regexp.Regexp, val interface{}) error
with no use of struct tags, because you get 80-125% of the value, while dodging all the previous problems. I'd go ahead and say the user of the code is responsible for proper grouping, just describe how it needs to be, and check it at runtime. Especially if you use named capture groups, further removing issues of order.
Post reply on HN