profile
viewpoint

erlandsona/Bat-Vision 2

Google Project Tango Hackathon Depth Perception Project

erlandsona/AE_portfolio 1

Jekyll theme based on Grayscale Start Bootstrap theme

erlandsona/caldwell-hilt 1

Playin' around with Hilt as alternative to servant?

erlandsona/cal_haskell 1

Trying to learn Haskell for great good!

bdfinlayson/tic-tac-toes-app 0

A game of fingers and toes

cphoniball/timer 0

Phoenix app to learn me some Elixir

elizabrock/median 0

NSS Cohort 8 Class Project / Medium clone

erlandsona/address-book 0

address book app assignment

erlandsona/after-brunch 0

A micro-plugin to run commands line scripts after Brunch's compile.

create barncherlandsona/opaque_types

branch : master

created branch time in 4 days

created repositoryerlandsona/opaque_types

created time in 4 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha cd7ad98d409a9d135efaa8324a74eceb68d3b349

Finish CH2, finally.

view details

push time in 5 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha b46f396c459042595b6e5357d98b34d4f77f7dc5

more answers.

view details

push time in 5 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha b3613f7f642bec7ff263d0149c29d696c0429065

2.22

view details

push time in 6 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha dc965de33728cd00459ffc1b5e7cd48fed88989d

More answers...

view details

push time in 11 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha 1e10bdead0ba6805f817c163d278d90c71ac2d81

WIP: ch2_answers.md

view details

push time in 12 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha 2bcb39cd7aa768ea2471af5184721a58414e64b6

WIP: ch2_answers.md

view details

push time in 12 days

push eventerlandsona/fpm_book

Austin Erlandson

commit sha 148eab326f17838970914ba98aca2a1d8f5a12fe

WIP: ch2_answers.md

view details

push time in 12 days

create barncherlandsona/fpm_book

branch : master

created branch time in 17 days

created repositoryerlandsona/fpm_book

Answers to exercises from Paul Orland's FP with Math

created time in 17 days

issue closeddigitallyinduced/ihp

Syntax and Higher level features

Curious where the #fieldName syntax comes from? I'm familiar with the -XTypeApplications extension I see being used to reference @User but the only reference to the pound symbol I found in the code base was in TH.

Also how do you handle more complex UI cases like Pagination+Infinite Scroll, or how/do you see a use case for generalizing certain CUD operations and what would/could that look like in IHP? I imagine Queries will always have to be fairly custom but along those lines generally pagination can / should be applied to anything that returns a list, no? Generally, I'm excited about the potential of the framework but I wonder how it compares to a Tierless approach like Lamdera (Elm), Eliom (OCaml), or Blazor (F#)?

closed time in 25 days

erlandsona

issue commentdigitallyinduced/ihp

Syntax and Higher level features

Took me a second to make the connection to -XOverloadedLabels extension which provides the #name syntax desugaring. But that makes sense!

Pagination while e.g. Lamdera is more a application runtime :)

fair enough.

erlandsona

comment created time in 25 days

issue openeddigitallyinduced/ihp

Syntax and Higher level features

Curious where the #fieldName syntax comes from? I'm familiar with the -XTypeApplications extension I see being used to reference @User but the only reference to the pound symbol I found in the code base was in TH.

Also how do you handle more complex UI cases like Pagination+Infinite Scroll, or how/do you see a use case for generalizing certain CUD operations and what would/could that look like in IHP? I imagine Queries will always have to be fairly custom but along those lines generally pagination can / should be applied to anything that returns a list, no? Generally, I'm excited about the potential of the framework but I wonder how it compares to a Tierless approach like Lamdera (Elm), Eliom (OCaml), or Blazor (F#)?

created time in a month

issue commentreasonml/reason-react

Maybe let's make a better `useState`?

Sorry to necrobump this but ran into this today helping out my coworkers try and modify some existing ReasonReact code to use local state instead of reductive.

I think that useState has to make a choice about which JS signature to support in the external is generally fine. Where we got burnt was that the compiler is unifying the Js.t('a) with the signature of the setProperty function returned by useState when it should be throwing a compile error.

I see in the documentation there's a comment about returning a Dom.eventTarget, curious when that update will land because that'd prevent this issue from happening in the future.

Regarding the Synthetic event issue which in #476 because of unification there's a number of places in code where we've used the setter like e => e->ReactEvent.Form.target##value->setProperty which incorrectly unifies the 'a type parameter which is ultimately just a raw string with the string => string function the setProperty function expects but it works because React ultimately handles both cases.

jaredly

comment created time in a month

issue commentelixir-ecto/ecto

`ago(integer, String.t())` not workin' in more complex query...

Ah!!! Thanks! makes sense!

erlandsona

comment created time in a month

issue commentelixir-ecto/ecto

`ago(integer, String.t())` not workin' in more complex query...

Ah yup... sorry forgot to add that to this... here we go :)

      # NOTE: This left_join on review_cadence may be irrelevant
      # unless a particular HP wants patients reviewed
      # sooner than "after 1 year on service".
      left_join:
        review_cadence in fragment(
          # Healthplan, Initial review cadence, Follow up review cadence
          """
          (values
            ('Aetna', interval '1 year', interval '3 months'),
            ('Anthem', interval '1 year', interval '1 month')
          )
          """
        ),
      on: review_cadence.column1 == health_plan.label,
      as: :rc,
      where:
        age(
          greatest(
            discharge_info.initial_active_date,
            discharge_info.reinstatement_date
          )
        ) > coalesce(review_cadence.column2, ago(1, "year")),
      where: ^not_reviewed_since_last_cadence(),
...

defp not_reviewed_since_last_cadence do
    dynamic(
      [r: review, rc: cadence],
      coalesce(age(review.latest) > coalesce(cadence.column3, ago(3, "month")), true)
    )
end

There's more to the query but it compiles down to the sql I mentioned earlier and the issue is replicable via the raw sql snippet.

erlandsona

comment created time in a month

issue openedelixir-ecto/ecto

`ago(integer, String.t())` not workin' in more complex query...

When I stumbled on the ago helper I was excited to be able to delete my manual construction of a %Postgrex.Interval{} struct and a helper to construct them for months. But when I substituted my usage of the raw values for the ago(-3, "month") in my query I got this error...

** (Postgrex.Error) ERROR 42804 (datatype_mismatch) COALESCE types interval and timestamp without time zone cannot be matched

    query: SELECT ...
WHERE (a0."ownerid" = $1) AND (age(greatest(a1."initial_active_date__pc", a1."date_reinstated__pc", NULL, NULL, NULL, NULL, NULL)) > coalesce(f7."column2", $2::timestamp + ($3::numeric * interval '1 year'))) AND (coalesce(age(s6."latest") > coalesce(f7."column3", $4::timestamp + ($5::numeric * interval '1 month')), TRUE)) AND (NOT (coalesce((a1."discharge_date__pc" = greatest(a1."discharge_date__pc", a1."initial_active_date__pc", a1."date_reinstated__pc", NULL, NULL, NULL, NULL)) OR (a1."date_of_death__pc" = greatest(a1."date_of_death__pc", a1."initial_active_date__pc", a1."date_reinstated__pc", NULL, NULL, NULL, NULL)), FALSE)))

Which I believe points to this snippet in the query $3::timestamp + (-5::decimal::numeric * interval '1 month'); which if you replace the $3 with an interval EG: select interval '0 month'::timestamp + (-5::decimal::numeric * interval '1 month'); you get the same error message from Postgres.

From the docs for the function apparently that $3 is supposed to be a DateTime.utc_now but I can't find the implementation for the ago function.

created time in a month

issue commentetsy/kevin-middleware

Can you provide any larger examples of Kevin in the wild?

Wanted to say thank you so much for your response. I brought it up in our architecture meeting and we seem to think this would require more structural changes to implement. Those same changes should lead to webpack's hot realoading being able to handle file changes more gracefully. After which, kevin-middleware might serve us better. But due to the fact that we generate our HTML from webpack and it sounds my team agrees our issue is more structural we're gonna pursue a light re-structuring first then maybe come back to this.

erlandsona

comment created time in 2 months

issue commentmobily/re-date

Curious about a Duration type

So I just stuck one of these in my project... Date.re

[@decco]
type interval = {
  months: int,
  days: int,
  secs: int,
  microsecs: int,
};

Then to get years I'm using let (years, months) = Relude.Int.divideWithModulo(months, 12) to get the years / months but I'd prefer to stick that in a decode function that serializes my shape into a Duration type to be used in conjunction with an external to formatDuration although, I'm not a fan of the signature of that function. I'd prefer something that won't throw exceptions on bad input.

erlandsona

comment created time in 2 months

issue commentetsy/kevin-middleware

Can you provide any larger examples of Kevin in the wild?

Hey @salemhilal

  1. webpack.config.js
const path = require('path')
const childProcess = require('child_process')
const { EnvironmentPlugin, DefinePlugin, IgnorePlugin } = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CircularDependencyPlugin = require('circular-dependency-plugin')
const GenerateJsonPlugin = require('generate-json-webpack-plugin')
const { GenerateSW } = require('workbox-webpack-plugin')

// The environment that our application runs in, used to determine which
// configuration to load and to set environment flags
const APP_ENV = process.env.APP_ENV || 'development'

// For local development - what app is being served via the devServer, portal
// or clinet
const APP_TO_SERVE = process.env.APP_TO_SERVE || 'projectClient'

// Whether the application is being built in a development environment
const DEV = process.env.NODE_ENV !== 'production'

const CDN =
  APP_ENV === 'production'
    ? 'cdn'
    : APP_ENV === 'testing'
    ? 'testing-cdn'
    : 'staging-cdn'

// URLs for caching and html templating
const URL = {
  PROJECT_ICONS: `https://${CDN}.projecthealth.io/ahc-fonts/css/Project-Icons.min.css`,
  MATERIAL_ICONS: 'https://fonts.googleapis.com/icon?family=Material+Icons',
  ROBOTO_FONT: 'https://fonts.googleapis.com/css?family=Roboto|Roboto+Mono',
  KAUSHAN_FONT:
    'https://fonts.googleapis.com/css?family=Kaushan+Script&display=swap',
}

const entry = DEV
  ? {}
  : { auth: path.resolve(__dirname, 'src/utils/security/auth') }

const CLIENT = new HtmlWebpackPlugin({
  filename: 'index.html',
  inject: 'head',
  template: path.resolve(__dirname, 'src/index.html'),
  excludeChunks: ['auth', 'runtime~auth', 'portal', 'runtime~portal'],
  templateParameters: {
    URL,
  },
})

const PORTAL = new HtmlWebpackPlugin({
  filename: DEV ? 'index.html' : 'partner/index.html',
  inject: 'head',
  template: path.resolve(__dirname, 'src/index.html'),
  excludeChunks: ['auth', 'runtime~auth', 'main', 'runtime~main'],
  templateParameters: {
    URL,
  },
})

// Build a single index.html for loacl dev, for either the client or portal -
// and build both for deployment environments
const HTML_WEBPACK_PLUGINS = (() => {
  if (DEV && APP_TO_SERVE === 'partnerPortal') return [PORTAL]
  if (DEV) return [CLIENT]
  return [CLIENT, PORTAL]
})()

// Build a primary keycloak.json for either the client or portal -
// and build both for deployment environments
const {
  primary: PRIMARY_KEYCLOAK,
  portal: PORTAL_KEYCLOAK,
} = require(path.resolve(__dirname, 'keycloak', `${APP_ENV}.keycloak.js`))({
  BUILD_PORTAL: DEV && APP_TO_SERVE === 'portal',
})

module.exports = {
  name: 'client',
  mode: DEV ? 'development' : 'production',
  devtool: DEV ? 'cheap-module-eval-source-map' : 'source-map',
  entry: {
    ...entry,
    polyfill: '@babel/polyfill',
    main: path.resolve(__dirname, 'src/index'),
    portal: path.resolve(__dirname, 'src/partnerPortal/index'),
    // These are packages that we think will take up the bulk of the bundle
    // size, but will also change relatively infrequently
    vendor: [
      '@devexpress/dx-react-core',
      '@devexpress/dx-react-grid',
      '@devexpress/dx-react-grid-material-ui',
      '@material-ui/core',
      '@material-ui/icons',
      '@material-ui/styles',
      'axios',
      'history',
      'immutable',
      'jss',
      'keycloak-js',
      'moment',
      'react',
      'react-dom',
      'react-redux',
      'redux',
      'redux-form',
      'redux-immutable',
      'redux-observable',
      'redux-routable',
      'redux-routable-react',
      'rxjs',
    ],
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    publicPath: '/',
    // Uses 'hash' in development to cache-bust
    filename: `[name].[${DEV ? '' : 'chunk'}hash].js`,
  },
  devServer: {
    port: 5000,
    publicPath: '/',
    contentBase: path.join(__dirname, 'public'),
    historyApiFallback: true,
  },
  watchOptions: {
    ignored: /node_modules/,
  },
  module: {
    strictExportPresence: true,
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          query: { cacheDirectory: true },
        },
      },
      {
        test: /\.css$/,
        use: [DEV ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader'],
      },
      {
        test: /\.md$/,
        use: 'raw-loader',
      },
      {
        test: /\.(png|svg|gif|jpe?g)$/i,
        use: [
          {
            loader: 'file-loader',
          },
        ],
      },
    ],
  },
  optimization: {
    runtimeChunk: true,
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: 'vendor',
          name: 'vendor',
          chunks: 'all',
        },
      },
    },
  },
  resolve: {
    alias: {
      '~': path.resolve(__dirname, 'src'),
      // Bucklescript compiled js output
      bs: path.resolve(__dirname, 'lib/es6_global/src'),
      'ahc-config': path.join(__dirname, 'src', 'ahc-config'),
      'redux-form': 'redux-form/immutable',
      'react-dom': '@hot-loader/react-dom',
    },
  },
  plugins: [
    new EnvironmentPlugin({
      NODE_ENV: 'development',
      APP_ENV: 'development',
    }),
    new DefinePlugin({
      __TEST__: APP_ENV === 'test',
      __DEV__: APP_ENV === 'development',
      __TESTING__: APP_ENV === 'testing',
      __STAGING__: APP_ENV === 'staging',
      __PROD__: APP_ENV === 'production',
      __EXPERIMENTAL__: !['staging', 'production'].includes(APP_ENV),
      __DEBUG_INFO__: {
        ['Built at']: JSON.stringify(new Date().toLocaleString()),
        ['Commit SHA']: JSON.stringify(
          childProcess.execSync('git rev-parse HEAD').toString()
        ),
      },
    }),
    new HtmlWebpackPlugin({
      filename: 'auth.html',
      inject: 'head',
      title: 'Project Healthcare Login',
      chunks: ['auth', 'runtime~auth', 'vendor'],
    }),
    ...HTML_WEBPACK_PLUGINS,
    new MiniCssExtractPlugin({
      filename: DEV ? '[name].css' : '[name].[hash].css',
      chunkFilename: DEV ? '[id].css' : '[id].[hash].css',
    }),
    new CircularDependencyPlugin({
      allowAsyncCycles: false,
      cwd: process.cwd(),
      exclude: /a\.js|node_modules/,
      failOnError: true,
    }),
    new GenerateSW({
      cacheId: 'project',
      clientsClaim: true,
      runtimeCaching: [
        {
          handler: 'CacheFirst',
          options: {
            cacheableResponse: { statuses: [0, 200] },
            cacheName: 'project-cdn-cache',
            expiration: { maxAgeSeconds: 24 * 60 * 60 },
          },
          urlPattern: new RegExp(Object.values(URL).join('|')),
        },
        {
          handler: 'CacheFirst',
          options: {
            cacheableResponse: { statuses: [0, 200] },
            cacheName: 'project-files-cache',
            expiration: { maxAgeSeconds: 24 * 60 * 60 },
          },
          urlPattern: /(.*)(favicon|keycloak\.json|site\.webmanifest)(.*)/,
        },
        {
          handler: 'CacheFirst',
          options: {
            cacheableResponse: { statuses: [0, 200] },
            cacheName: 'project-fonts-cache',
            expiration: { maxAgeSeconds: 24 * 60 * 60 },
          },
          urlPattern: /(.*)(ahc-fonts|gstatic)(.*)/,
        },
        {
          handler: 'NetworkFirst',
          options: {
            cacheableResponse: { statuses: [0, 200] },
            cacheName: 'project-json-cache',
            expiration: { maxAgeSeconds: 24 * 60 * 60 },
            networkTimeoutSeconds: 5,
          },
          // Endpoints required to load an Assessment
          urlPattern: /(.*)(actionable_items|field_values)(.*)/,
        },
      ],
      skipWaiting: true,
    }),
    new GenerateJsonPlugin('keycloak.json', PRIMARY_KEYCLOAK),
    new GenerateJsonPlugin('partner/keycloak.json', PORTAL_KEYCLOAK),
    // Exclude Moment.js locale files (except for the default "en" locale)
    new IgnorePlugin(/^\.\/locale$/, /moment$/),
  ],
}
  1. Ideally kevin would replace webpack-dev-server but only incrementally serve what it needs too? (Not really sure how it works in this regard or how to set things up to get kevin to do it's magic)
  2. I literally copy/pasted the example from the readme as a jumping off point. Haven't done much except fix the syntax error
const kevin = new Kevin(webpackConfig, {
  kevinPublicPath: 'http://localhost:3000', // this has kevinPublicPath = 'http://localhost'
})
erlandsona

comment created time in 2 months

issue openedetsy/kevin-middleware

Can you provide any larger examples of Kevin in the wild?

I'm trying to spin up kevin as a proof of concept for our client and running into... after following the example... not really sure how to resolve.

:9275/:1 GET http://localhost:9275/ 404 (Not Found)
localhost/:1 Refused to load the image 'http://localhost:9275/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

I read the article you posted and thought Kevin would be a great fit for our codebase as well. We've got about 3500 js files and webpack-dev-server takes anywhere from a minute or so to build on first launch and about 10-12 seconds for a given change in watch mode.

So the promise of being able to incrementally build portions of the app to speed up development time for a monorepo seems like a very promising solution for our needs as well.

created time in 2 months

issue commentAstrocoders/lenses-ppx

Inspired by #10

Honestly, I don't have much experience with them given we've only just started using Reason at my company the past few months and I only have experience doing Haskell in my free time so I never used the lense lib but I know of it, why it exists, and this would be my first experience getting to put lenses in production so mostly I was looking for some larger scale examples.

Based on my limited understanding of Optics Prism's would give us the ability to handle custom variants as options and Traversals for say rendering an list of say html `li's?

erlandsona

comment created time in 2 months

issue openedAstrocoders/lenses-ppx

Inspired by #10

What about generating Prisms, Traversals, or other optics? I'm also curious about how these compose... I've got some heavy enough usage of nested |> Option.map(x => x.prop) and |> Option.flatMap(x => x.prop) stuff, and I'm wondering if making use of this library might give me some better ergonomics.

created time in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

Any thoughts on this @ryb73 ?

erlandsona

comment created time in 2 months

issue openedmobily/re-date

Curious about a Duration type

I'm returning a Postgres interval to my client via EctoInterval which serializes a Postgrex.Interval into some Json that looks like {secs: 0, months: 50, microsecs: 0, days: 25}... I'd like to be able to serialize that into something I can pass to date-fns/formatDuration. For now I'll make my own Duration record but it'd be nice if this lib had a solution for it 🤷‍♂️

created time in 2 months

pull request commentdanielberkompas/destructure

Handle stringly keyed maps!

@danielberkompas ?

erlandsona

comment created time in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

Alrighty I'm back at my machine... Powers on and all is right with the world 😆

RE: Is it not sufficient to get the location information at the call site when it fails?

It is sufficient to configure the location information at the call site when it fails but I don't believe that a special "Debugging" (compiler hook?) should be something the callers have to be aware of to benefit from.

I don't really see the value of baking it into the library?

Aside from my answer to the first point here's some code...

CodingQuery.re

module Record = {
  module Id = ID.Int();

  [@decco]
  type t = {
    id: Id.t,
    submission: string,
    submittedById: UserT.Id.t,
    submittedBy: UserT.record,
    submittedAt: Date.t,
    encounterId: EncounterT.Id.t,
    encounter: EncounterT.record,
    response: option(string),
    respondedById: option(UserT.Id.t),
    respondedBy: option(UserT.record),
    respondedAt: option(Date.t),
  };

  // consider using lenses-ppx to push this definition into Tabular.
  let pkey = x => x.id;
};

// Spits out a Data (Map.t) module and a View (Html Table Component) module.
module Table = Tabular.Make(Record);

module ResponseT = {
  type data = Async.t(StatusT.t);
  type action =
    | Change(Record.Id.t, string)
    | Send(Record.Id.t, EncounterT.Id.t, data);
};

type state = Async.t(Table.t);
type action =
  | Fetch(state)
  | Response(ResponseT.action);

let init = AsyncResult.init;
let reduce: (state, action) => state =
  Relude_Function.curry2(
    fun
    | (_, Fetch(a)) => a
    | (state, Response(a)) => state->Response.reduce(a),
  );

let encounterFetch = (id: EncounterT.Id.t) =>
  Request.make(
    ~creator=x => CodingQuery(Fetch(x)),
    API.get(
      "/coding_dashboard/queries/" ++ id->EncounterT.Id.show,
      ~decode=CodingQueryT.Table.t_decode,
    ),
  );

let appsList = (viewingAs: UserT.Id.t) =>
  Request.make(
    ... // Action creator, optional selector, optional toast message options.
    API.get(
      "/coding_dashboard/queries",
      ~decode=CodingQueryT.Table.t_decode,
      ~params={"viewingAs": viewingAs->UserT.Id.view},
    ),
  );
...

Basically this is how we do Safe-ish HTTP stuff safely hookin' into our Reductive / Bs-rx infra...

Notice each API.get call is required to pass a ~decode function.

As it stands currently if either of these decoders fail say because the id prop in the Record.t is the wrong type (which has happened to us in production at this point a few times now) currently we're Js.loging the Decco.decodeError record so we get this {path: "[0].id", message: "Not a int", value: nil} which doesn't point to this particular Record.t as we have a bunch of types with id properties. So debugging this took me a good while to track down.

Preferably and what this PR add's to the project is that it forces callers of the Decco.typeFromJson functions to pass __LOC__ as an argument. Sort of forces callers into the happy path with the minimal amount of boilerplate.

Without these changes the callers would have to do something like ~decode=CodingQueryT.Table.t_decode >> Result.catchError(_ => Js.log("Failure at "++__LOC__), which is fine but it's not enforced and because it's extra work chances are people won't do it.

It also doesn't fix the location info for the messages pointing to failures for decco generated decoders like the id property on that Record.t type...

These changes result in an error with some location info baked in EG: {path: "[0].id File "CodingQuery.re", line 8, characters 5-20", message: "Not a int", value: nil} which tells the developer where exactly the failure occurred for a generated Decco decoder.

Which! Is why I'd generally prefer to bake it into the lib in a more transparent way but that's where I'd need your help @ryb73. Otherwise, I think these changes build in enough value as they are to solve for at least my teams use case and I hope they can be helpful to others using this as well.

erlandsona

comment created time in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

Two things...

  1. When we use the decco annotation for a type without the location info if any of the decoders for properties on that type fail it's not always clear from the name of the property which type or which file is defining the property that's failing to decode.

  2. For custom decoders unless there's a way to pull location information of the call site there's no way to force calling code to provide location information for themselves in the future.

My power just went out so I'm typing this up on my phone otherwise I'd have more complete examples to share here. But I'm hoping I'm making enough sense otherwise.

erlandsona

comment created time in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

I'm not a fan of the breaking API change that'll force users writing "custom decoders" with the Codecs to pass an argument, it's better in that it'll force callers into a debuggable pattern but I wish I could code gen location info for failures directly to call sites of stuff...

erlandsona

comment created time in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

@rickyvetter Of course! If you take a look at the test files you can see a direct comparison of what the before/after messages look like. https://github.com/reasonml-labs/decco/pull/55/files#diff-4887d5e04c82d3ad103e1500793d43e6 https://github.com/reasonml-labs/decco/pull/55/files#diff-a24b1337669f9c22a77d36a098c12a98

erlandsona

comment created time in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

@ryb73 you have any thoughts on this?

erlandsona

comment created time in 2 months

issue commentreazen/relude

Relude_Unsafe shadows our projects Unsafe module which has more stuff in it.

Feel free to close this if you feel so inclined 👌

erlandsona

comment created time in 2 months

issue commentreazen/relude

Relude_Unsafe shadows our projects Unsafe module which has more stuff in it.

In any case, I'm glad I asked because I'm probably gonna go down the route @johnhaley81's suggesting! @mlms13 glad you're still alive! Haha

erlandsona

comment created time in 2 months

issue openedreazen/relude

Relude_Unsafe shadows our projects Unsafe module which has more stuff in it.

Consider removing Relude_Unsafe from Relude.Globals to avoid shadowing in the event developers want to define their own Unsafe module for externals to js functions that can throw RTE's. We could rename ours to like Risky.re or something but convention for fn's that can throw is to prefix them with Unsafe so I'd prefer if we could define our own unsafe module but still open Relude.Globals at the top of files. Generally I'm fine with qualifying Relude.Unsafe.coerce for the few times we need that function. Alternatively expose coerce at the top-level of Relude.Globals like composition >>?

created time in 2 months

push eventerlandsona/destructure

Austin Erlandson

commit sha ddd2606f84c76294907a54d27b5a5b938aba3e7c

Change to s macro because d(%s{}) should be kept when assigning a Struct to a pattern variable, and d(s%{}) gets mix formatted to d(s(%{})) which is ugly.

view details

push time in 2 months

PR opened danielberkompas/destructure

Handle stringly keyed maps!
+35 -4

0 comment

1 changed file

pr created time in 2 months

push eventerlandsona/destructure

Austin Erlandson

commit sha 1904c8e761027f644b1085395d7f2e36e9f42ba5

Handle stringly keyed maps!

view details

push time in 2 months

push eventerlandsona/destructure

Austin Erlandson

commit sha 4e8602932dc72b8047b6550d6dd456d1f6c319fa

Handle stringly keyed maps!

view details

push time in 2 months

fork erlandsona/destructure

Javascript-style destructuring for Elixir

fork in 2 months

pull request commentreasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

So I finished this version but I'd really like some input or help making this interface less invasive to calling code... It really stinks to 1 have a major version bump in the API and 2 to force callers to have to pass __LOC__ into all the codecs when building a custom decoder.

Generally I'd prefer if we could do more PPX magic and somehow generate the Location info wherever something like Decco.intFromJson is used.

erlandsona

comment created time in 3 months

push eventerlandsona/decco

Austin Erlandson

commit sha a9f537f0fa9dc6d9a7dec473ea7dbdc3ad4afb8a

Finish gross version with passing tests... need to refactor to use a differen key than 'path' for the location information.

view details

push time in 3 months

issue commentjaredly/reason-language-server

1.7.8 crashing (OSX 10.13.3)

Posting here so as not to muddy the issue list waters.

2 coworkers are having issues with reason-language-server vscode plugin 1.7.8 crashing on OSX 10.15.4

Here's the error output...

[Error - 11:08:32 AM] Request textDocument/codeLens failed.
Error: Connection got disposed.
    at Object.dispose (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/main.js:825:25)
    at Object.dispose (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-languageclient/lib/client.js:57:35)
    at LanguageClient.handleConnectionClosed (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-languageclient/lib/client.js:1967:42)
    at LanguageClient.handleConnectionClosed (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-languageclient/lib/main.js:126:15)
    at closeHandler (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-languageclient/lib/client.js:1954:18)
    at CallbackList.invoke (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/events.js:71:39)
    at Emitter.fire (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/events.js:135:36)
    at closeHandler (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/main.js:221:26)
    at CallbackList.invoke (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/events.js:71:39)
    at Emitter.fire (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/events.js:135:36)
    at StreamMessageReader.AbstractMessageReader.fireClose (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/messageReader.js:135:27)
    at Socket.<anonymous> (/Users/AJP/.vscode/extensions/jaredly.reason-vscode-1.7.8/node_modules/vscode-jsonrpc/lib/messageReader.js:188:62)
    at Socket.emit (events.js:208:15)
    at Pipe.<anonymous> (net.js:588:12)

Hoping to get some more Troubleshooting ideas cause we're goin' through the debug settings and we've tried most of the .

boyswan

comment created time in 3 months

PR opened reasonml-labs/decco

Enforce callers pass a path for debugging purposes, and update ppx to…

… generate better location info for decode failures.

So this is just a first pass at upgrading decco for better location information on decode errors. I haven't update the tests yet because I'm not sure how to fix this issue where it seems like the Pervasives.__LOC__ calls are being evaluated when the ppx is run rather than printing that expression for bucklescript to compile.

If I someone can help me figure that part out then I can fix the tests and we all can go from this {path: "[0].id", message: "Not a int", value: nil} to something more along the lines of this... {path: "[0].id File "MyCustomRecord.re", line 8, characters 7-60", message: "Not an int", value: nil}

+54 -61

0 comment

6 changed files

pr created time in 3 months

push eventerlandsona/decco

Austin Erlandson

commit sha ac052c52a7bee108c3a4d49245b4a742ba881d9e

Enforce callers pass a path for debugging purposes, and update ppx to generate better location info for decode failures.

view details

push time in 3 months

fork erlandsona/decco

Bucklescript PPX which generates JSON (de)serializers for user-defined types

fork in 3 months

more