Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

With Great Nerdery Comes Great Responsibility

1,236 views

Published on

Delivered at Pittsburgh Perl Workshop 2014.

Published in: Internet
  • Be the first to comment

With Great Nerdery Comes Great Responsibility

  1. 1. With Great Power Comes Great Responsibility John SJ Anderson § @genehack PPW2014 § 2014-11-08
  2. 2. Nerder y With Great Power Comes Great Responsibility John SJ Anderson § @genehack PPW2014 § 2014-11-08
  3. 3. image: http://25.media.tumblr.com/tumblr_m69bglG75B1r72cw7o1_500.jpg
  4. 4. is there anybody in here that hasn't heard that? you're the product. image: https://c1.staticflickr.com/7/6170/6185789175_41f41c843d_z.jpg
  5. 5. and i don't mean to just pick on Facebook here -- the "you're the product" business model is industry standard. image: https://twitter.com/danlyke/status/529826711324876802
  6. 6. hell, even if you _are_ paying for a service, that doesn't stop the service owner from making you into the product image: http://www.forbes.com/sites/kashmirhill/2014/10/28/att-says-its-testing-unkillable-tracker-on-customers-smartphones/
  7. 7. My name is John and this is my manifesto i have feels.
  8. 8. many feels image: http://www.hnldesign.nl/wp-content/uploads/2013/02/The-Manifesto-Manifesto.jpg
  9. 9. We're nerds. We can do better. the people in this room have the ability to do things that not many people can do. we need to step up and do something about this.
  10. 10. We can do better for our friends and family too. and we need to do it in such a way that we lift up the people we care about. we can't just make tools for ourselves, we have to make tools for normal people too.
  11. 11. Some recent exemplary efforts not everything is bad news. there are other people that have started trying to do stuff about this too.
  12. 12. ftrain's tilde.club screencap by speaker
  13. 13. brennen's squiggle.city screencap by speaker
  14. 14. full of stuff that looks like this.
  15. 15. see, here's the thing -- the internet didn't use to be like this. image: http://img1.wikia.nocookie.net/__cb20110515062056/simpsons/images/3/38/Abe.png
  16. 16. i got on the internet in 1989. i read usenet groups on a vt220 at the university of iowa. (before endless september!) image: http://i.imgur.com/2MhE2.jpg
  17. 17. years later, in 1998, i started one of the first weblogs and was part of an incredibly active and vibrant community that was convinced -- at least some of us were convinced -- that what we were doing, sharing our thoughts and cross-linking things and snarking about politics -- was going to change everything. left: http://www.theage.com.au/ffximage/2007/04/06/svBLOG_narrowweb__300x506,0.jpg right: http://robiospeaks.files.wordpress.com/2010/06/peter-merholz.png
  18. 18. and we were right. photo: stevan little
  19. 19. except for the comments. i apologize for the whole commenting thing, in retrospect it was a really bad idea. image: https://img0.etsystatic.com/011/0/7887463/il_fullxfull.438911204_gfot.jpg
  20. 20. so enough "good old days" nonsense. i pointed out some people that were trying to do something about this -- what am _i_ trying to do? image: no idea. i am a bad person and i feel bad.
  21. 21. there are a number of things i have on my todo list for 2015: moving away from google, replacing "free" services with services i pay for, or even better, write myself. image: https://i.imgflip.com/bjr2p.jpg
  22. 22. but for this talk, i want to focus on twitter. image:http://edudemic.com/wp-content/uploads/2013/04/twitter1.gif
  23. 23. I ❤️ Twitter. i really like twitter-the-service. i'm on twitter a _lot_. twitter has helped me hire people, it's been essential in making friends after i moved across the country a couple years ago, and it's how i keep up with the vast majority of my friends.
  24. 24. I ⃠❤️ Twitter. i'm not quite as big a fan of twitter-the-company. they don't seem to have a great idea of what direction they're going in, and their attempts at monetization and attracting new users have me increasingly concerned for the future of twitter-the-service.
  25. 25. Thinking about solutions. Or even just mitigations. Options. Escape hatches. so i'm thinking about ways to solve those problems, or even just reduce them. thinking about where i could go, if it came down to that. thinking about what would be in my "go bag".
  26. 26. Inspiration. one of the best benefits of my job is getting to hang out with people that make me want to do better.
  27. 27. http://micro.sartak.org/
  28. 28. • Archive • Search • Potential Escape Hatch great, because it does the stuff that shawn wanted it to do.
  29. 29. doesn't do everything i want though.
  30. 30. So I started writing Klatsch.
  31. 31. • Archive • Search • Potential Escape Hatch • Feed reading / management • Posting (micro- and macro-blogging) • RSS reader • Hub for online social activity in general
  32. 32. • Archive • Search Note: almost all currently aspirational... • Potential Escape Hatch • Whole Feed • Posting (micro- and macro-blogging) • RSS reader • Hub for online social activity in general
  33. 33. Most importantly: Easy deployment. I want other people to be able to run their own copies of this software too. Centralization of this sort of thing provides an incentive towards silo-a-zation, and that's the beginning of the bad times.
  34. 34. Which, yes, means:
  35. 35. Not Perl Perl deployments are horrible.
  36. 36. #sorry
  37. 37. #sorrynotsorry
  38. 38. Best deployment story around, currently:
  39. 39. Go.
  40. 40. Go (aka golang) • Statically typed (w/inference) • Compiled (cross-platform) • C-like syntax & design • Garbage collected • Excellent concurrency support • Interesting approach to OO
  41. 41. But, most importantly: Statically-linked. Binaries. Deployment == trivial.
  42. 42. package main import "fmt" func main() { fmt.Print("Hello world") } this is hello world in go.
  43. 43. % ls -­‐sh hello 1.8M hello* static linking == big binaries
  44. 44. but it doesn't matter. image: http://www.quickmeme.com/img/3b/3b0241c9f06118600eaa2271ac5a0e11c619bc72a2a547d6883c8f62a2dc7a58.jpg
  45. 45. So... Klatsch.
  46. 46. package main import ( "fmt" "github.com/spf13/cobra" ) func main() { var cmdFetch = &cobra.Command{ Use: "fetch", Short: "fetch", Long: "long fetch", Run: fetch, } var Force bool cmdFetch.PersistentFlags().BoolVarP(&Force, "force", "F", false, "build HTML page even if nothing has changed") var cmdImportTweets = &cobra.Command{ Use: "import_tweets", Short: "import", Long: "long import", Run: func(cmd *cobra.Command, args []string) { fmt.Println("import_tweets not implemented yet.") }, } ... var rootCmd = &cobra.Command{Use: "klatsch"} rootCmd.AddCommand(cmdFetch, cmdImportTweets, cmdInit, cmdSearch, cmdServer) rootCmd.Execute() }
  47. 47. import ( ... "github.com/ChimeraCoder/anaconda" "github.com/spf13/cobra" ) func fetch(cmd *cobra.Command, args []string) { var force bool = false if cmd.Flag("force").Value.String() == "true" { force = true } exitUnlessDatabaseExists() db := getDatabaseHandle() defer db.Close() twitter := getTwitterApiHandle(db) v := url.Values{"count": {"200"}} timeline, err := twitter.GetUserTimeline(v) if err != nil { log.Fatal(err) } inserted, err := saveTimeline(db, timeline) if err != nil { log.Fatal(err) } if force || inserted > 0 { if err = writeOutTimeline(db); err != nil { log.Fatal(err) } } }
  48. 48. import ( ... "github.com/ChimeraCoder/anaconda" "github.com/spf13/cobra" ) func fetch(cmd *cobra.Command, args []string) { var force bool = false if cmd.Flag("force").Value.String() == "true" { force = true } exitUnlessDatabaseExists() db := getDatabaseHandle() defer db.Close() twitter := getTwitterApiHandle(db) v := url.Values{"count": {"200"}} timeline, err := twitter.GetUserTimeline(v) if err != nil { log.Fatal(err) } inserted, err := saveTimeline(db, timeline) if err != nil { log.Fatal(err) } if force || inserted > 0 { if err = writeOutTimeline(db); err != nil { log.Fatal(err) } } } You can take the boy out of Perl...
  49. 49. import ( ... "github.com/ChimeraCoder/anaconda" "github.com/spf13/cobra" ) func fetch(cmd *cobra.Command, args []string) { var force bool = false if cmd.Flag("force").Value.String() == "true" { force = true } exitUnlessDatabaseExists() db := getDatabaseHandle() defer db.Close() twitter := getTwitterApiHandle(db) v := url.Values{"count": {"200"}} timeline, err := twitter.GetUserTimeline(v) if err != nil { log.Fatal(err) } inserted, err := saveTimeline(db, timeline) if err != nil { log.Fatal(err) } if force || inserted > 0 { if err = writeOutTimeline(db); err != nil { log.Fatal(err) } } }
  50. 50. Live demo!
  51. 51. Live demo! (safest live demo evar.)
  52. 52. <!DOCTYPE html> <html lang="en" data-­‐ng-­‐app="klatsch"> <head> <meta charset="utf-­‐8"> <title>Klatsch!</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/klatsch.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="col-­‐md-­‐3"></div> <div class="col-­‐md-­‐6"> <h1>Postin'</h1> <twitter-­‐input></twitter-­‐input> </div> <div class="col-­‐md-­‐3"></div> </div> <div class="footer"> <div class="container"> <p class="text-­‐muted">Powered by Klatsch!</p> </div> </div> <script src="http://code.angularjs.org/1.2.26/angular.min.js"></script> <script src="js/directives.js"></script> </body> </html>
  53. 53. <!DOCTYPE html> <html lang="en" data-­‐ng-­‐app="klatsch"> <head> <meta charset="utf-­‐8"> <title>Klatsch!</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/klatsch.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="col-­‐md-­‐3"></div> <div class="col-­‐md-­‐6"> <h1>Postin'</h1> <twitter-­‐input></twitter-­‐input> </div> <div class="col-­‐md-­‐3"></div> </div> <div class="footer"> <div class="container"> <p class="text-­‐muted">Powered by Klatsch!</p> </div> </div> <script src="http://code.angularjs.org/1.2.26/angular.min.js"></script> <script src="js/directives.js"></script> </body> </html>
  54. 54. directive("twitterInput", function () { return { restrict: "E" , replace: true , templateUrl: "./twitter_input.html" , controller: function($scope,$timeout) { $scope.error = function(name) { var form = $scope.form[name]; return form.$invalid && form.$dirty ? "has-­‐error" : ""; }; }, scope: {} }; })
  55. 55. <form name="form" role="form"> <div class="form-­‐group" data-­‐ng-­‐class="error('postfield')"> <div class="controls"> <input type="text" name="postfield" class="form-­‐control" data-­‐ng-­‐trim=false counted-­‐max="140" data-­‐ng-­‐model="post.content" placeholder="Compose new tweet" /> </div> <div class="pull-­‐right" style="margin:5px 0;"> <span class="help-­‐block inline-­‐display" data-­‐ng-­‐show="form.postfield.$error.unique"> Post is too long! </span> <span class="count" style="margin-­‐right:5px" data-­‐ng-­‐class="error('postfield')"> {{140 -­‐ post.content.length}} </span> <button class="btn btn-­‐primary" data-­‐ng-­‐click="postToTwitter(account)" data-­‐ng-­‐disabled="!form.$valid"> Post to Twitter </button> </div> </div> </form>
  56. 56. .directive("countedMax", function() { return { require: "ngModel" , restrict: "A" , link: function(scope,element,attrs,ngModelCtrl) { var maxlength = Number(attrs.countedMax); function fromUser(text) { ngModelCtrl.$setValidity( 'unique', text.length <= maxlength ); return text; } ngModelCtrl.$parsers.unshift(fromUser); } }; })
  57. 57. Live demo 2: search
  58. 58. So that's what I'm trying to do about it.
  59. 59. what can _you_ do about it? image: http://memestorage.com/_nw/21/04359364.jpg
  60. 60. Just use the app and give me feedback. once it's ready, I mean. image: http://memestorage.com/_nw/21/04359364.jpg
  61. 61. http://www.poststat.us/wp-content/uploads/2013/12/patches-welcome-752x361.jpg
  62. 62. Or write your own tool! (and then we can figure out how to make them work together!) http://treasure.diylol.com/uploads/post/image/399053/resized_jesus-says-meme-generator-jesus-says-do-it-yourself-ffe55f.jpg
  63. 63. Reminder.
  64. 64. http://lesquestionscomposent.fr/wp-content/uploads/2013/03/23353915.jpg
  65. 65. https://github.com/genehack/klatsch
  66. 66. https://github.com/genehack/klatsch questions?

×