Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to cast int/double <-> string #78

Closed
unode opened this issue Sep 3, 2018 · 1 comment
Closed

Ability to cast int/double <-> string #78

unode opened this issue Sep 3, 2018 · 1 comment

Comments

@unode
Copy link
Member

unode commented Sep 3, 2018

Motivation:

seq.filter(min_identity_pc=ARGV[1])

fails to typecheck since ARGV[] are strings.

and similarly:

cutoff = 95
...
seq.filter(min_identity_pc=cutoff)
...
write(... ofile="/path/file_" + cutoff + ".txt")

Will either fail on the first if cutoff is a string or the second if an integer/double.


One possibility I explored was to add a method number.to_string() to all numeric types but I hit a limitation in that different types cannot have a method with the same name. The code compiles but when executed NGLess gives a confusing error (paraphrasing) method 'to_string' doesn't exist, did you mean 'to_string'?

So I ended up with:

diff --git a/NGLess/BuiltinFunctions.hs b/NGLess/BuiltinFunctions.hs
index 2486533..cb5d680 100644
--- a/NGLess/BuiltinFunctions.hs
+++ b/NGLess/BuiltinFunctions.hs
@@ -145,6 +145,11 @@ builtinMethods =
     ,MethodInfo (MethodName "avg_quality") NGLRead Nothing NGLDouble [] True []
     ,MethodInfo (MethodName "fraction_at_least") NGLRead (Just NGLInteger) NGLDouble [] True []
     ,MethodInfo (MethodName "n_to_zero_quality") NGLRead Nothing NGLRead [] True [FunctionCheckMinNGLessVersion (0,8)]
+
+    -- NGLDouble
+    ,MethodInfo (MethodName "double_to_string") NGLDouble Nothing NGLString [] True []
+    -- NGLInteger
+    ,MethodInfo (MethodName "int_to_string") NGLInteger Nothing NGLString [] True []
     ]
 
 filterArgs =
diff --git a/NGLess/Interpret.hs b/NGLess/Interpret.hs
index e99e54c..e97acdd 100644
--- a/NGLess/Interpret.hs
+++ b/NGLess/Interpret.hs
@@ -95,6 +95,7 @@ import Data.FastQ
 import NGLess.NGLEnvironment
 import NGLess.NGError
 
+import Interpretation.Language
 import Interpretation.Map
 import Interpretation.Count
 import Interpretation.FastQ
@@ -484,6 +485,8 @@ executePreprocess v _ _ = unreachable ("executePreprocess: Cannot handle this in
 executeMethod :: MethodName -> NGLessObject -> Maybe NGLessObject -> [(T.Text, NGLessObject)] -> InterpretationROEnv NGLessObject
 executeMethod method (NGOMappedRead samline) arg kwargs = runNGLess (executeMappedReadMethod method samline arg kwargs)
 executeMethod method (NGOShortRead sr) arg kwargs = runNGLess (executeShortReadsMethod method sr arg kwargs)
+executeMethod method (NGODouble double) arg kwargs = runNGLess (executeDoubleTypeMethod method double arg kwargs)
+executeMethod method (NGOInteger int) arg kwargs = runNGLess (executeIntegerTypeMethod method int arg kwargs)
 executeMethod m self arg kwargs = throwShouldNotOccur ("Method " ++ show m ++ " with self="++show self ++ " arg="++ show arg ++ " kwargs="++show kwargs ++ " is not implemented")
 
 
diff --git a/NGLess/Interpretation/Language.hs b/NGLess/Interpretation/Language.hs
new file mode 100644
index 0000000..9e54b17
--- /dev/null
+++ b/NGLess/Interpretation/Language.hs
@@ -0,0 +1,22 @@
+{- Copyright 2015-2018 NGLess Authors
+ - License: MIT
+ -}
+
+{-# LANGUAGE RankNTypes, FlexibleContexts #-}
+
+module Interpretation.Language
+    ( executeDoubleTypeMethod
+    , executeIntegerTypeMethod
+    ) where
+
+import Data.Text (pack)
+import Language
+import NGLess
+
+executeDoubleTypeMethod :: MethodName -> Double -> Maybe NGLessObject -> KwArgsValues -> NGLess NGLessObject
+executeDoubleTypeMethod (MethodName "double_to_string") number Nothing [] = return . NGOString . pack . show $ number
+executeDoubleTypeMethod m self arg kwargs = throwShouldNotOccur ("Method " ++ show m ++ " with self="++show self ++ " arg="++ show arg ++ " kwargs="++show kwargs ++ " is not implemented")
+
+executeIntegerTypeMethod :: MethodName -> Integer -> Maybe NGLessObject -> KwArgsValues -> NGLess NGLessObject
+executeIntegerTypeMethod (MethodName "int_to_string") number Nothing [] = return . NGOString . pack . show $ number
+executeIntegerTypeMethod m self arg kwargs = throwShouldNotOccur ("Method " ++ show m ++ " with self="++show self ++ " arg="++ show arg ++ " kwargs="++show kwargs ++ " is not implemented")

Alternatively I also considered a function to_string(variable) but ran into similar limitations in that different functions are necessary to handle different types.

The above code doesn't address the ARGV[] -> int/double use-case. I'd probably go for string.to_int() and string.to_double() and error if the transformation isn't possible.

Any suggestions on better ways to address the need for casting variables?

@luispedro
Copy link
Member

Not having the ability to have more than one method with the same name across different types is obviously a silly limitation.

luispedro added a commit that referenced this issue Dec 4, 2020
Addresses #78 in one direction (int/double -> str)

Make the method machinery more general, allowing different types to
have methods with the same name (closes #85)
luispedro added a commit that referenced this issue Dec 4, 2020
Addresses #78 in one direction (int/double -> str)

Make the method machinery more general, allowing different types to
have methods with the same name (closes #81)
luispedro added a commit that referenced this issue Dec 4, 2020
These are very simple. The choice of API was to allow for a default on
empty, but to error on anything else that cannot be parsed

This patch also adds the ``__assert`` function for internal use and
generalizes some of the transformation mechanics

closes #78
luispedro added a commit that referenced this issue Jan 25, 2021
An accummulation of improvements rather than a big new feature is what
triggers the new release.

Full `ChangeLog`:

- Better error message if the user attempts to use the non-existent <\> operator (suggest </>)
- Add min-ngless-version field for modules
- Add early check that block assignments are always to block variables
- Use ZStd compression for temporary files from preprocess()
- Correctly handle subpaths in samples for collect (fixes #141)
- Add to_string() to int and double types (partially fixes #78 & fixes #81)
- Add read_int() and read_double() functions (fixes #78)
luispedro added a commit that referenced this issue Jan 26, 2021
An accummulation of improvements rather than a big new feature is what
triggers the new release.

Full `ChangeLog`:

- Validate count() headers on --validate-only
- Better error message if the user attempts to use the non-existent <\> operator (suggest </>)
- Add min-ngless-version field for modules
- Add early check that block assignments are always to block variables
- Use ZStd compression for temporary files from preprocess()
- Correctly handle subpaths in samples for collect (fixes #141)
- Add to_string() to int and double types (partially fixes #78 & fixes #81)
- Add read_int() and read_double() functions (fixes #78)
luispedro added a commit that referenced this issue Jan 26, 2021
An accummulation of improvements rather than a big new feature is what
triggers the new release.

Full `ChangeLog`:

- Validate count() headers on --validate-only
- Better error message if the user attempts to use the non-existent <\> operator (suggest </>)
- Add min-ngless-version field for modules
- Add early check that block assignments are always to block variables
- Use ZStd compression for temporary files from preprocess()
- Correctly handle subpaths in samples for collect (fixes #141)
- Add to_string() to int and double types (partially fixes #78 & fixes #81)
- Add read_int() and read_double() functions (fixes #78)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants