DEV Community

Discussion on: Typing your way into safety

Collapse
 
isra17 profile image
Israël Hallé

I think to keep the same spirit, I would abstract it in another layer. I would define a function resize that takes in an int. As for specific range, NewType could also be used the same way we did for strings:

Size = NewType("Size", int)

def parse_size(unsafe_size: str) -> Size:
  size = int(size_str)
  return valid_size(size)


def valid_size(unsafe_size: int) -> Size:
  if size > 2000:
    raise ValueError("Too big!")
  return size

# int as str are always safe for shell!
def shell_int(x: int) -> ShellQuotedString:
  return str(x)

def resize(size: Size) -> None:
  command = shell_format("convert INPUT -resize {} OUTPUT", shell_int(size))
  system(command)

resize(parse_size("123")) # ok
resize(valid_size(123)) # ok
resize(123) # error!
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tlavoie profile image
tlavoie

OK, that makes sense thanks. As long as you're strict about only accepting the appropriate typed versions at the command input, enforcement works. I think what is missing is the equivalent of Haskell's enforcing of types everywhere; this is a useful tool, but you have to pay attention to make sure it's used consistently.

Having it enforced everywhere would be more of a challenge I suppose, because there isn't really the equivalent of that compile-time checking in a more dynamic environment.